跨项目gRPC开发:.proto文件共享与部署时的访问方式咨询
跨项目gRPC共享proto文件的部署时访问方案
JVM客户端(sbt项目)
不要依赖进程启动目录的相对路径,改用类路径加载——shared/src/main/resources下的文件会被sbt自动打包到模块的JAR包根目录,属于应用的classpath资源,无论进程从哪个目录启动,类加载器都能定位到:
代码调整示例
import com.google.protobuf.ProtoLoader import java.net.URL // 从类路径加载proto文件的URL val protoUrl: URL = getClass.getResource("/api.proto") val packageDefinition = ProtoLoader.loadSync(protoUrl)
如果ProtoLoader支持输入流,也可以这样写:
import com.google.protobuf.ProtoLoader import java.io.InputStream val protoStream: InputStream = getClass.getResourceAsStream("/api.proto") val packageDefinition = ProtoLoader.loadSync(protoStream)
确保sbt配置正确
如果是多模块项目,客户端模块必须依赖shared模块,确保shared的资源能被客户端加载:
lazy val client = project .dependsOn(shared) .settings( // 其他项目配置 )
Node.js服务端
避免硬编码相对路径,用Node.js的path模块结合当前文件目录定位,或在构建阶段同步proto文件到固定目录:
动态路径定位(适用于目录结构固定的场景)
假设Node.js项目根目录与shared目录同级,代码示例:
const path = require('path'); const grpc = require('@grpc/grpc-js'); const protoLoader = require('@grpc/proto-loader'); // 基于当前文件目录向上追溯,定位到shared目录下的proto文件 const protoPath = path.resolve(__dirname, '../shared/src/main/resources/api.proto'); const packageDefinition = protoLoader.loadSync(protoPath);
构建阶段同步文件(更稳妥的部署方案)
在package.json中添加同步脚本,构建时把proto文件复制到Node.js项目的固定资源目录,部署时直接从该目录加载:
{ "scripts": { "sync-proto": "cp ../shared/src/main/resources/api.proto ./resources/", "build": "npm run sync-proto && 你的构建命令" } }
部署时加载固定路径:
const protoPath = path.resolve(__dirname, './resources/api.proto'); const packageDefinition = protoLoader.loadSync(protoPath);
额外优化方案
把shared目录做成Git子模块,让JVM和Node.js项目都依赖这个子模块,既能保证两边proto文件版本一致,又能基于子模块的固定路径加载文件,避免目录结构变动导致的路径问题。
内容的提问来源于stack exchange,提问作者user79074
相关产品推荐
相关产品推荐

