Skip to content

Commit

Permalink
create server and client for nestjs
Browse files Browse the repository at this point in the history
  • Loading branch information
zgid123 committed Apr 16, 2023
1 parent 5ea3285 commit f1c41e9
Show file tree
Hide file tree
Showing 22 changed files with 861 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"husky": "^8.0.3",
"lint-staged": "^13.2.1",
"prettier": "^2.8.7",
"rollup": "^3.20.2",
"rollup": "^3.20.3",
"turbo": "^1.9.1",
"typescript": "^5.0.4"
},
Expand Down
4 changes: 4 additions & 0 deletions packages/nestjs/client/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.turbo
src
tsconfig.json
rollup.config.ts
126 changes: 126 additions & 0 deletions packages/nestjs/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
NestJS's Dynamic Module for Client.

# Install

```sh
npm install --save @grpc.ts/nestjs-client

# or

yarn add @grpc.ts/nestjs-client

# or

pnpm add @grpc.ts/nestjs-client
```

# Usage

```proto
// example.proto
syntax = "proto3";
import "google/protobuf/timestamp.proto";
package example.v1;
message Message {
string message = 1;
google.protobuf.Timestamp created_at = 2;
}
message SendMessageRequest {
string message = 1;
google.protobuf.Timestamp created_at = 2;
}
message GetMessageResponse { Message message = 1; }
service ExampleService {
rpc SendMessage(SendMessageRequest) returns (GetMessageResponse);
}
```

In NestJS

```ts
// client.module.ts
import { Module } from '@nestjs/common';
import { GrpcClient } from '@grpc.ts/nestjs-client';

import { ClientController } from './client.controller';

@Module({
imports: [
GrpcClient.register([
{
url: 'localhost:3010',
package: [
{
packageName: 'example.v1',
protoPath: '../proto/example.proto',
},
{
packageName: 'example2.v1',
protoPath: '../proto/example2.proto',
},
{
protoPath: '../proto/example3.proto',
},
],
packageDefinitionOptions: {
oneofs: true,
longs: String,
enums: String,
defaults: true,
},
options: {
keepaliveTimeMs: 5_000,
},
},
]),
],
controllers: [ClientController],
})
export class ClientModule {}
```

```ts
// client.controller.ts
import { Controller, Get } from '@nestjs/common';
import {
GrpcService,
createMetadata,
dateToGrpcTimestamp,
} from '@grpc.ts/nestjs-client';

@Controller('/client')
export class ClientController {
constructor(
@GrpcService({
serviceName: 'ExampleService',
})
private readonly exampleService: any,
) {}

@Get()
public async sendMessage(): Promise<string> {
this.exampleService
.sendMessage(
{ message: 'hello', createdAt: dateToGrpcTimestamp(new Date()) },
createMetadata({
meta: 'test',
}),
)
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});

return 'Ok!';
}
}
```
46 changes: 46 additions & 0 deletions packages/nestjs/client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@grpc.ts/nestjs-client",
"version": "1.0.0",
"license": "MIT",
"directories": {
"lib": "lib"
},
"author": "Alpha",
"description": "NestJS package for client",
"homepage": "https://github.com/zgid123/grpc-ts",
"keywords": [
"grpc",
"grpc-ts",
"grpc-js",
"grpc-typescript",
"grpc-javascript",
"grpc-nodejs",
"grpc-nestjs",
"grpc-client"
],
"repository": {
"type": "git",
"url": "git+https://github.com/zgid123/grpc-ts"
},
"main": "./lib/index.cjs",
"module": "./lib/index.mjs",
"types": "./lib/index.d.ts",
"exports": {
".": {
"import": "./lib/index.mjs",
"require": "./lib/index.cjs",
"types": "./lib/index.d.ts"
}
},
"scripts": {
"prepublish": "pnpm build",
"build": "rollup --config rollup.config.ts --configPlugin typescript"
},
"dependencies": {
"@grpc.ts/core": "workspace:*",
"@nestjs/common": "^9.4.0"
},
"devDependencies": {
"@grpc.ts/client-commons": "workspace:*"
}
}
21 changes: 21 additions & 0 deletions packages/nestjs/client/rollup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineConfig } from 'rollup';
import json from '@rollup/plugin-json';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript';

export default defineConfig({
input: 'src/index.ts',
plugins: [json(), resolve(), commonjs(), typescript()],
external: ['@nestjs/common', '@grpc.ts/core'],
output: [
{
file: './lib/index.cjs',
format: 'cjs',
},
{
file: './lib/index.mjs',
format: 'es',
},
],
});
61 changes: 61 additions & 0 deletions packages/nestjs/client/src/GrpcClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { createClients } from '@grpc.ts/client-commons';
import {
Module,
type Provider,
type DynamicModule,
type OnApplicationShutdown,
} from '@nestjs/common';

import type {
IGrpcClientProps,
IGrpcClientListProps,
} from '@grpc.ts/core/lib/interface';

import { normalizePattern } from './utils';

@Module({})
export class GrpcClient {
public static async register(
options: IGrpcClientProps | IGrpcClientProps[],
): Promise<DynamicModule> {
const clients = await createClients(options);

const providers = this._createProviders(clients);

return {
module: GrpcClient,
providers,
exports: providers,
};
}

protected static _createProviders(clients: IGrpcClientListProps): Provider[] {
return Object.entries(clients).reduce<Provider[]>(
(result, [clientName, clientWrapper]) => {
Object.entries(clientWrapper.getPackages()).forEach(
([packageName, serviceClientWrapper]) => {
Object.entries(serviceClientWrapper).forEach(
([serviceName, serviceClient]) => {
(
serviceClient as unknown as OnApplicationShutdown
).onApplicationShutdown = serviceClient.close;

result.push({
provide: normalizePattern({
serviceName,
clientName: clientName || '',
packageName: packageName || '',
}),
useValue: serviceClient,
});
},
);
},
);

return result;
},
[],
);
}
}
9 changes: 9 additions & 0 deletions packages/nestjs/client/src/decorators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Inject } from '@nestjs/common';

import { normalizePattern } from './utils';

import type { IGrpcServiceProps } from './interface';

export const GrpcService = (props: IGrpcServiceProps) => {
return Inject(normalizePattern(props));
};
9 changes: 9 additions & 0 deletions packages/nestjs/client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export {
Metadata,
createMetadata,
grpcTimestampToDate,
dateToGrpcTimestamp,
} from '@grpc.ts/core';

export * from './decorators';
export * from './GrpcClient';
5 changes: 5 additions & 0 deletions packages/nestjs/client/src/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface IGrpcServiceProps {
clientName?: string;
serviceName: string;
packageName?: string;
}
18 changes: 18 additions & 0 deletions packages/nestjs/client/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { IGrpcServiceProps } from './interface';

function combine(separator: string, ...data: string[]): string {
return data.filter((s) => !!s).join(separator);
}

export function normalizePattern({
serviceName,
clientName = '',
packageName = '',
}: IGrpcServiceProps): string {
return combine(
'::',
'grpc',
combine('::', clientName, packageName),
serviceName,
);
}
14 changes: 14 additions & 0 deletions packages/nestjs/client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./src",
"outDir": "./lib",
},
"include": [
"./src"
],
"exclude": [
"./lib",
"./node_modules"
]
}
4 changes: 4 additions & 0 deletions packages/nestjs/server/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.turbo
src
tsconfig.json
rollup.config.ts
Loading

0 comments on commit f1c41e9

Please sign in to comment.