{"id":21064170,"url":"https://github.com/moveaxlab/nestjs-grpc-client","last_synced_at":"2025-05-16T02:32:24.950Z","repository":{"id":170983009,"uuid":"644798681","full_name":"moveaxlab/nestjs-grpc-client","owner":"moveaxlab","description":"A dataloader implementation to talk with gRPC servers, with support for request merging and cross-request caching.","archived":false,"fork":false,"pushed_at":"2024-03-06T14:59:27.000Z","size":396,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-03T18:52:49.598Z","etag":null,"topics":["dataloader","graphql","grpc","nestjs"],"latest_commit_sha":null,"homepage":"","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/moveaxlab.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}},"created_at":"2023-05-24T09:26:40.000Z","updated_at":"2024-03-01T13:12:29.000Z","dependencies_parsed_at":"2023-06-28T14:32:01.524Z","dependency_job_id":null,"html_url":"https://github.com/moveaxlab/nestjs-grpc-client","commit_stats":null,"previous_names":["moveaxlab/nestjs-grpc-client"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moveaxlab%2Fnestjs-grpc-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moveaxlab%2Fnestjs-grpc-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moveaxlab%2Fnestjs-grpc-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moveaxlab%2Fnestjs-grpc-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moveaxlab","download_url":"https://codeload.github.com/moveaxlab/nestjs-grpc-client/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254456077,"owners_count":22074098,"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":["dataloader","graphql","grpc","nestjs"],"created_at":"2024-11-19T17:48:41.136Z","updated_at":"2025-05-16T02:32:21.340Z","avatar_url":"https://github.com/moveaxlab.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NestJS gRPC Client\n![NPM](https://img.shields.io/npm/l/%40moveaxlab%2Fgraphql-client)\n[![npm](https://img.shields.io/npm/v/@moveaxlab/nestjs-grpc-client)](https://www.npmjs.com/package/@moveaxlab/nestjs-grpc-client)\n![Static Badge](https://img.shields.io/badge/node_version-_%3E%3D20-green)\n\nThis library defines gRPC dataloaders you can inject dynamically in GraphQL resolvers in order to optimize calls via batching and caching.\n\nMore about the dataloader pattern at https://github.com/graphql/dataloader\n\n## Installation\n\n```bash\nyarn add @moveaxlab/nestjs-grpc-client\n```\n\n## Usage\n\n### Dataloaders\n\ngRPC dataloaders are based on gRPC clients defined as follows:\n```typescript\n// package.client.ts\nimport { GrpcClientForService } from '@moveax/nestjs-grpc-client';\nimport { grpcPkg } from 'somewhere'; // import also your autogenerated gRPC package\n\nexport type PackageClient = GrpcClientForService\u003c\n    grpcPkg.PackageServiceDefinition\n\u003e;\n// OR\nexport type PackageClientWithStreamingMethods = GrpcClientForService\u003c\n    grpcPkg.PackageServiceDefinition,\n    'myClientStreamingMethod' | 'myBidirectionalStreamingMethod'\n\u003e;\n```\n\nImplement your gRPC dataloader:\n```typescript\n// package.dataloader.ts\nimport { Metadata } from '@grpc/grpc-js';\nimport { GrpcDataLoaderProvider, DataLoaderForClient, Request, createDataLoaderDecorator } from '@moveax/nestjs-grpc-client';\nimport { Injectable, Logger } from '@nestjs/common';\nimport { PackageClient } from 'package.client';\nimport { grpcPkg } from 'somewhere'; // import also your autogenerated gRPC package\n\n@Injectable()\nexport class PackageDataLoaderProvider extends GrpcDataLoaderProvider\u003cPackageClient\u003e {\n    client: PackageClient;\n    logger = new Logger(PackageDataLoaderProvider.name);\n\n    createMetadata(_: Request): Metadata {\n        const metadata = new Metadata();\n        // you can use the Express' request token to authenticate also the gRPC call \n        metadata.set('authorization', req.get('authorization'));\n        return metadata;\n    }\n\n   get cacheConfig() {\n      return {\n         someMethod: {\n            cacheKeyFn: (request: grpcPkg.ISomeMethodRequest) =\u003e {\n               return `pkgService.someMethod:${input.param1}-${input.param2}`;\n            },\n            ttl: 60,\n         },\n      };\n   }\n}\n\nexport const PackageService = createDataLoaderDecorator(PackageDataLoaderProvider.prototype);\n\nexport type PackageDataloader = DataLoaderForClient\u003cPackageClient\u003e;\n```\n\n1. The `cacheConfig` getter returns an object containing cache configuration for the various methods.\n   If a method needs to be cached, the `cacheConfig` must contain an entry for that method that takes in input\n   the method request and returns a string, which will be used as the cache key. A TTL can be specified,\n   that will be used if global caching is enabled (see below).\n2. The `PackageService` is an object containing a parameter decorator for each method of the gRPC client.\n   You can use the decorator in your resolvers to obtain an instance of the dataloader (see below).\n3. The `PackageDataloader` is a type containing the types of each method dataloader.\n   You can use the type in your resolvers to add type safety to your loaders.\n\nAdd the `GrpcDataLoaderInterceptor` to your app in order to load dataloaders relevant for the request at runtime:\n```typescript\nimport { Module } from '@nestjs/common';\nimport { APP_INTERCEPTOR } from '@nestjs/core';\nimport { GrpcDataLoaderInterceptor } from '@moveax/nestjs-grpc-client';\n\n@Module({\n  provides: [\n    {\n      provide: APP_INTERCEPTOR,\n      useClass: GrpcDataLoaderInterceptor,\n    }\n  ],\n  /* ... */\n})\nexport class AppModule {}\n```\n\nNow you can use the dataloader in your resolvers:\n```typescript\n// imports omitted for lack of will\n\n@Resolver()\nclass Whatever {\n    @Query()\n    async getWhatever(\n        @PackageService.someMethod() loader: PackageDataloader['someMethod']\n    ) {\n        const response = await loader.load(/* gRPC request */);\n        // do whatever you want with the response now\n    }\n}\n```\n\n### Batching requests\n\nTo batch several requests to a given service when doing API composition,\nspecify the `mergeConfig` inside your dataloader provider.\n\nThe `mergeConfig` provides two properties for each endpoint:\n- `mergeInput`, that takes an array of requests and combines them to a single request\n- `splitOutput`, that takes the original array of requests and a single response,\n  and splits it into an array of responses\n\n### Global caching\n\nTo use global caching, pass `true` to the loader decorator:\n```typescript\n// imports omitted for lack of will\n\n@Resolver()\nclass Whatever {\n    @Query()\n    async getWhatever(\n        @PackageService.someMethod(true) loader: PackageDataloader['someMethod']\n    ) {\n        const response = await loader.load(/* gRPC request */);\n        // do whatever you want with the response now\n    }\n}\n```\n\nThe `ttl` must be set to something greater than 0 inside the cacheConfig\nfor the dataloader, for global caching to work. _The TTL is expressed in seconds._\n\nAll requests to that specific dataloader will be cached for `ttl` seconds,\nin a cache shared between all calls. __Use global caching with care:__ the global cache will skip all authorization logic\nthat may live inside your backend services.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoveaxlab%2Fnestjs-grpc-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoveaxlab%2Fnestjs-grpc-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoveaxlab%2Fnestjs-grpc-client/lists"}