{"id":14976087,"url":"https://github.com/single9/node-grpc-graphql-server","last_synced_at":"2026-03-14T18:57:23.757Z","repository":{"id":38207837,"uuid":"305275384","full_name":"single9/node-grpc-graphql-server","owner":"single9","description":"Generates GraphQL schemas from gRPC Protocol Buffers and creates the server or gRPC client.","archived":false,"fork":false,"pushed_at":"2024-05-31T03:45:43.000Z","size":1722,"stargazers_count":11,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-01T07:31:38.430Z","etag":null,"topics":["graphql","graphql-schema","graphql-server","grpc","grpc-client","grpc-server","node","nodejs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/grpc-graphql-server","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/single9.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-19T05:46:22.000Z","updated_at":"2024-05-31T03:45:47.000Z","dependencies_parsed_at":"2024-09-27T21:40:31.872Z","dependency_job_id":"7c34239f-28e5-48da-a99c-832ad6501356","html_url":"https://github.com/single9/node-grpc-graphql-server","commit_stats":{"total_commits":244,"total_committers":3,"mean_commits":81.33333333333333,"dds":"0.032786885245901676","last_synced_commit":"f4ed54b97910723bae2690077daad493cd95d6fa"},"previous_names":[],"tags_count":64,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/single9%2Fnode-grpc-graphql-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/single9%2Fnode-grpc-graphql-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/single9%2Fnode-grpc-graphql-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/single9%2Fnode-grpc-graphql-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/single9","download_url":"https://codeload.github.com/single9/node-grpc-graphql-server/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238536015,"owners_count":19488639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","graphql-schema","graphql-server","grpc","grpc-client","grpc-server","node","nodejs"],"created_at":"2024-09-24T13:53:16.964Z","updated_at":"2025-10-27T17:32:13.393Z","avatar_url":"https://github.com/single9.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gRPC GraphQL Server\n\n![test](https://github.com/single9/node-grpc-graphql-server/workflows/test/badge.svg?branch=master) ![npm](https://github.com/single9/node-grpc-graphql-server/workflows/npm/badge.svg) [![codecov](https://codecov.io/gh/single9/node-grpc-graphql-server/branch/main/graph/badge.svg?token=EWQFDL2X0N)](https://codecov.io/gh/single9/node-grpc-graphql-server)\n\n## Installation\n\n    npm install express @grpc/proto-loader apollo-server-express grpc-graphql-server @graphql-tools/schema\n\n### (Optional) gRPC JS runtime library\n\nInstall [grpc-tools](https://github.com/grpc/grpc-node/tree/master/packages/grpc-tools) to generates gRPC JS runtime library\n\n    npm i -D grpc-tools\n\nAnd install [google-protobuf](https://www.npmjs.com/package/google-protobuf) for google's protobuf runtime library.\n\n    npm i google-protobuf\n\nAfter installation, you can now build the gRPC JS clinet/pb. See [here](#generate-grpc-js-runtime-library-experimental).\n\n## Usage\n\n### Server\n\nCreate a file named `hello.proto` and put it into directory `conf/rpc`.\n\nThe location of the file is specified by the environment `RPC_CONFS`. Default is `/conf/rpc`.\n\nAlso, you can modify it by pass `protoFile` to the constructor.\n\nSee `examples/helloworld`.\n\n```\nsyntax = \"proto3\";\n\npackage helloworld;\n\n// The greeting service definition.\nservice Greeter {\n  // Sends a greeting\n  rpc SayHello (HelloRequest) returns (HelloReply) {}\n  // Sends another greeting\n  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}\n}\n\n// The request message containing the user's name.\nmessage HelloRequest {\n  string name = 1;\n}\n\n// The response message containing the greetings\nmessage HelloReply {\n  string message = 1;\n}\n```\n\nCreate a file named index.js. This is your server.\n\n```js\nconst app = require(\"express\")();\nconst RPCServer = require(\"grpc-graphql-server\").RPCServer;\n\nfunction response(resData, callback) {\n  // for gRPC\n  if (typeof callback === \"function\") {\n    return callback(null, resData);\n  }\n\n  // for grapgql\n  return new Promise((resolve, reject) =\u003e {\n    resolve(resData);\n  });\n}\n\nclass Hello {\n  SayHello(call, callback) {\n    return response(\n      {\n        message: \"Hello \" + call.request.name,\n      },\n      callback\n    );\n  }\n\n  SayHelloAgain(call, callback) {\n    return response(\n      {\n        message: \"Hello again \" + call.request.name,\n      },\n      callback\n    );\n  }\n}\n\nconst methods = {\n  hello: new Hello(),\n};\n\nconst rpcServer = new RPCServer({\n  // port: 50052,    // uncomment to set gRPC port on 50052\n  graphql: true, // Set true to enable GrpahQL because it's not enabled by default.\n  grpc: {\n    // protoFile: __dirname + '/protos/hello.proto', // set the protobuf file path.\n    packages: [\n      {\n        name: \"helloworld\",\n        services: [\n          {\n            name: \"Greeter\",\n            implementation: methods.hello,\n            mutate: false, // set true to add this service to the mutation\n            // also you can set individual function of service to specified type.\n            // It will be added to the type you specified.\n            //mutate: [\n            //  \"SayHello\"\n            //]\n          },\n        ],\n      },\n    ],\n  }\n});\n\nrpcServer.once(\"grpc_server_started\", async (payload) =\u003e {\n  console.log(\"gRPC server started at \" + payload);\n});\n\nif (rpcServer.gqlServer) {\n  rpcServer.gqlServer.applyMiddleware({ app });\n}\n\napp.listen(3000, () =\u003e {\n  console.log(\"Server started. http://localhost:3000\");\n});\n```\n\npackages can also be like this:\n\n```js\nconst rpcServer = new RPCServer({\n  ...\n  grpc: {\n    packages: {\n      helloworld: { // package name\n        Greeter: {  // service name\n          implementation: methods.hello, // implementation\n        },\n      },\n    },\n  },\n  ...\n});\n```\n\n### Client\n\nSee `examples/helloworld/grpc-client.js`.\n\n```js\nconst { RPCClient } = require(\"grpc-graphql-server\");\nconst rpcClient = initRPCClient({\n  // protoFile: __dirname + '/protos', // Set this if your protobuf file doesn't located in the default directory.\n  packages: [\n    {\n      name: \"helloworld\",\n      services: [\n        {\n          name: \"Greeter\",\n          // port: 50052,  // Uncomment this to set gRPC client port to 50052\n        },\n      ],\n    },\n  ],\n});\n\nasync function main() {\n  // call with callback\n  rpcClient.helloworld.Greeter.SayHelloAgain(\n    { name: \"test again\" },\n    function (err, response) {\n      if (err) return console.log(\"no response\");\n      console.log(\"Greeting again:\", response.message);\n    }\n  );\n\n  // call with promise\n  const sayHelloResponse = await rpcClient.helloworld.Greeter.SayHello({\n    name: \"test\",\n  });\n  const SayNestedResponse = await rpcClient.helloworld.Greeter.SayNested({});\n  console.log(\"Greeting\", sayHelloResponse.message);\n  console.log(SayNestedResponse);\n}\n\nmain();\n```\n\npackages can also be like this:\n\n```js\nconst rpcClient = initRPCClient({\n  ...\n  packages: {\n    helloworld: { // package name\n      Greeter: {  // service name\n        //port: 50051, // gRPC service port number\n      },\n    },\n  },\n  ...\n});\n```\n\n### gRPC Metadata\n\n**Since Version 0.3.14**\n\nIf you want to add metadata to your gRPC call, just pass `metadata` to the function.\n\n```\n{\n  metadata: [\n    ['metadata_key', 'value']\n  ]\n}\n```\n#### Add Metadata to Client\n\n```js\n// call with callback and metadata\nrpcClient.helloworld.Greeter.SayHello({ name: 'test' }, { metadata: [['time', Date.now()]] }, (err, response) =\u003e {\n    if (err) return console.log('no response');\n    console.log('Greeting:', response.message);\n  });\n\n// call with promise and metadata\nconst sayHelloResponse = await rpcClient.helloworld.Greeter.SayHello({ name: 'test' }, { metadata: [['time', Date.now()]] });\n```\n\n**Get Metadata in Server**\n\nGet metadata by `call.metadata`. This is a Map object so we can get the metadata very easily.\n\n```js\nclass Hello extends Controller {\n  SayHello(call, callback) {\n    // get metadata from grpc call\n    console.log(call.metadata.get('time'))\n    return this.response({\n      message: `Hello ${call.request.name}`,\n    }, callback);\n  }\n}\n```\n\n### GraphQL\n\n    npm install graphql-request graphql\n\n#### Usage\n\n```js\nconst { request, gql } = require(\"graphql-request\");\n\nconst query = gql`\n  {\n    \u003cpackage_name\u003e {\n      \u003cservice_name\u003e {\n        \u003cfunction_name\u003e(request: \u003crequest_parameters\u003e) {\n          \u003cresponse_data_type\u003e\n        }\n      }\n    }\n  }\n`;\n\nrequest(\"http://localhost:3000/graphql\", query).then((data) =\u003e\n  console.log(data)\n);\n```\n\n#### Example\n\nSee `examples/helloworld/graphql-client.js`.\n\n```js\nconst { request, gql } = require(\"graphql-request\");\nconst query = gql`\n  {\n    helloworld {\n      Greeter {\n        SayHello(request: { name: \"Duye\" }) {\n          message\n        }\n      }\n    }\n  }\n`;\n\nrequest(\"http://localhost:3000/graphql\", query).then((data) =\u003e\n  console.log(JSON.stringify(data))\n);\n```\n\n### Manually GraphQL Schema and Resolver\n\nThis package generates GraphQL schema and resolver from gRPC protocol buffers by default. Now you can\nspecify your own GraphQL schema and resolver to the server.\n\nThanks to [w4567892015](https://github.com/w4567892015) with [PR#4](https://github.com/single9/node-grpc-graphql-server/pull/4).\n\n#### Usage\n\n```js\nconst rpcServer = new RPCServer({\n  ...\n  graphql: {\n    enable: true,   // Set true to enable GrpahQL because it's not enabled by default.\n    // auto: false, // Set false to disable default GraphQL generator if you don't need.\n    schemaPath: 'path/to/your/graphql/schema.js',\n    resolverPath: 'path/to/your/graphql/resolver.js',\n    // apolloConfig: { // other config you want to configure\n    //   tracing: true\n    //}\n  },\n  ...\n});\n```\n\n#### Context\n\nWe use [ApolloServer](https://www.apollographql.com/) to build our GraphQL server. It provides `context` argument for passing things\nthat any resolver might need, like authentication, databases, etc.\n\nRef: ([The context argument - ApolloServer](https://www.apollographql.com/docs/apollo-server/data/resolvers/#the-context-argument))\n\n```js\nconst rpcServer = new RPCServer({\n  ...\n  graphql: {\n    ...\n    context: async ({ req }) =\u003e {\n      console.log(req);\n    }\n  },\n  ...\n});\n```\n\n##### Example\n\n**Server**\n\nSee `examples/helloworld-alt`.\n\n```js\nconst rpcServer = new RPCServer({\n  protoFile: __dirname + \"/protos/hello.proto\", // set the protobuf file path. (string|string[])\n  graphql: {\n    enable: true, // Set true to enable GrpahQL because it's not enabled by default.\n    schemaPath: path.join(__dirname, \"./schema\"),\n    resolverPath: path.join(__dirname, \"./controllers/graphql\"),\n  },\n  grpc: {\n    packages: [\n      {\n        name: \"helloworld\",\n        services: [\n          {\n            name: \"Greeter\",\n            implementation: methods.hello,\n            mutate: false,\n          },\n        ],\n      },\n    ],\n  },\n});\n```\n\n## Events\n\n**Since Version 0.3.1**\n\nWe add events to let you can handle more, such as client errors.\n\n**Usage**\n\nOnly client need.\n\n```js\nconst client = initRPCClient({\n  originalClass: true,\n});\n\nclient.on(\"grpc_client_error\", (err) =\u003e console.log(err));\n```\n\n### Event: Server\n\n**grpc_server_started**\n\nFired when grpc server is started.\n\n- Payload\n  - ip: server ip\n  - port: server port\n\n### Event: Client\n\n**grpc_client_error**\n\nFired when grpc client got error.\n\n- Payload\n  - error: gRPC errors ([Status Response Codes](https://developers.google.com/maps-booking/reference/grpc-api/status_codes))\n  - call:\n    - service: Service Name\n    - functionName: Function name\n    - request: Function request parameters\n\n## Notes\n\n### Package Name\n\nIf your package name is `topname.subname.v1`, it will replaced the `.` to `_`. So your new package\nname in the server will be `topname_subname_v1`.\n\n#### Example of Client Usage\n\n```js\nrpcClient['topname_subname_v1'].\u003cservice_name\u003e.method({ a: 1 }, function (err, response) {\n  // ...\n});\n\nawait rpcClient['topname_subname_v1'].\u003cservice_name\u003e.method({ a: 1 });\n```\n\n# Generate gRPC JS runtime library (experimental)\n\n**Since Version 0.4.x**\n\n**NOTE:** GraphQL and generated gRPC runtime library cannot be used at the same time.Maybe one day I will found a better way to do.\n\nIf you want to use generated js runtime library for server side, you should install `grpc-tools` and run the command below:\n\n    npx grpc-graphql-server init \u003cproto_files_dir\u003e \u003cgrpc_js_out_dir\u003e\n\ne.g.\n\n    npx grpc-graphql-server init ./protos/ ./grpc\n\n## Server\n\n```js\nconst rpcServer = new RPCServer({\n  grpc: {\n    protoFile: `${__dirname}/protos/`,\n    // Add this to read the generated code\n    generatedCode: {\n      outDir: `${__dirname}/grpc-pb`,\n    },\n    packages: {\n      helloworld: {\n        Greeter: {\n          implementation: Hello,\n        },\n      },\n      calculator: {\n        Simple: {\n          implementation: Calculator,\n        },\n        Complex: {\n          implementation: Calculator,\n        }\n      },\n    },\n  },\n});\n```\n\nYou can see details on `example/generated-grpc-code`\n\n# Migration from v0.3.x\n\n## gRPC\n\nWe move the grpc parameters form constructor root to `grpc` object. This change only affect `RPCServer`.\n\n**v0.3.x**\n\n```js\nconst rpcServer = new RPCServer({\n  packages: [\n    {\n      name: \"helloworld\",\n      services: [\n        {\n          name: \"Greeter\",\n        },\n      ],\n    },\n  ],\n});\n```\n\n**v0.4.x**\n\n```js\nconst rpcServer = new RPCServer({\n  grpc: { // we move it inside this object\n    packages: [\n      {\n        name: \"helloworld\",\n        services: [\n          {\n            name: \"Greeter\",\n          },\n        ],\n      },\n    ],\n  },\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsingle9%2Fnode-grpc-graphql-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsingle9%2Fnode-grpc-graphql-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsingle9%2Fnode-grpc-graphql-server/lists"}