@nclabs/nestjs-rpc-module
v0.2.25
Published
Utilitário NestJS para configuração de rotas e cache em microsserviços. Utilizado especificamente para projetos nclabs
Downloads
277
Readme
nestjs-nclabs-rpc-module
Utilitário NestJS para configuração de rotas e cache em microsserviços. Utilizado especificamente para projetos nclabs
Instalação
npm i @nclabs/nestjs-rpc-module
Configuração
Carregar o arquivo de configuração (ex.: docker-compose.env) compartilhado entre todos os serviços.
As váriáveis descritas no arquivo de configuração são carregadas e tratadas pela biblioteca de configuração.
Todas as variáveis de ambiente são expostas com seu nome original no atributo env da biblioteca de configuração.
Arquivo de configuração modelo: https://github.com/nclabs-npm/nestjs-nc-template/blob/main/dist/docker-compose.env
Variável de ambiente que DEVE ser setada no docker-compose.yml:
environment:
SERVICE_NAME: <your-service-name>
Variáveis de ambiente que PODEM ser setada no docker-compose.yml:
environment:
...
# Gerar log de repostas com sucesso
LOG_RESPONSE=<true | false>
# Nível de log dos erros
LOG_ERROR_LEVEL=<debug | info | warn | error | fatal>
Modulo
// app.module.ts
...
import { NclabsRpcModule } from '@nclabs/rpc-module';
@Module({
imports: [
// ...
NclabsRpcModule.register({
autoInterceptCache: true, // true ou false: default true
}),
// ...
],
// ...
})
export class AppModule {}
Recursos
| Recurso | Tipo | Uso | Observação | |--------------------------------------------------------|:-----------:|:--------------------:|--------------------------------------------------------------| | NclabsConfig | Lib | * | Disponibiliza todas as váriaveis de ambiente | | NclabsHttp | Decorator | Controller | Configura requisições HTTP | | NclabsAction | Decorator | Controller | Configura requisições RPC | | NclabsEvent | Decorator | Controller | Configura envio de eventos RPC | | NclabsCtx | Decorator | Controller | Acessa informações do contexto do microserviço | | NclabsContext | Interface | * | Tipo de contexto do microserviço | | NclabsRpcClientService | Provider | Controller Service | Métodos para requisição de microserviços externos (RPC conf) | | NclabsCacherService | Provider | Controller Service | Métodos para o tratamento manual do cache | | INclabsException | Interface | * | Tipo de exceção do microserviço |
NclabsConfig
const config = NclabsConfig.load();
console.log(config.service);
console.log(config.g5.baseUrl);
console.log(config.env.get('SERVICE_NAME'));
console.log(config.env.get('G5_BASE_URL'));
Controller - Method Configuration
// app.controller.ts
...
@Controller()
export class AppController {
...
/**
* HTTP REQUEST
*/
@NclabsAction({
path: 'your-path/:id',
methods: ['GET', 'POST'],
cache: {
keys: ['#headers.authorization', '#data.id', 'some-key'],
ttl: 1200, // seconds
},
})
youRpcMethodName(@NclabsCtx() context: NclabsContext) {
// Do something
return;
}
/**
* RPC CALL
*/
@NclabsAction({
name: 'your-action-name',
cache: {
keys: ['#headers.authorization', '#params.id', 'some-key'],
ttl: 1200, // seconds
},
})
youRpcMethodName(@NclabsCtx() context: NclabsContext) {
// Do something
return;
}
...
HTTP REQUEST:
Registra a rota definida em path
para os métodos indicados em methods
. Quando o parâmetro methods
não for informado, todos os métodos são permitidos.
No Exemplo acima:
- GET /your-path/:id
- POST /your-path/:id
RPC:
O método poderá ser requisitado pelo padrão service.name
Onde:
- service = SERVICE_NAME (definido no environment do docker compose)
- name = your-action-name (configurado no decorator do método)
CACHE:
O atributo cache
disponibiliza párâmetros de configuração do cache para o retorno da requisição com as chaves especificadas no keys
e com o TTL especificado no ttl
.
O cacher gera a chave do cache com base no serviço, protocolo (HTTP/RCP), nome do método e as chaves especificadas no keys
. Que aceita valores estaticos, variáveis previamente carregadas (lembrando que o NestJs carrega os decorator antes de instanciar os módulos) e variáveis do contexto que poderão ser acessadas
através do prefixo #
sendo possível utilizar qualquer atributo de retorno do contexto.
A sintaxe da chave é:
<SERVICE_NAME>:-.<key 1>.<key 2>.<key 3>
// Exemplo:
// SERVICE_NAME = senior-auth
@NclabsHttp({
path: '/user-credential:id',
methods: ['GET'],
cache: {
keys: [
'#headers.authorization', // value from context.headers
'#params.id', // value from context.params
'some-key' // static value
],
ttl: 1200, // seconds
},
})
getUserCredential(...) {
}
...
A chave gerada para o cache será algo assim:
senior-auth:http-get-getUserCredential.Bearer A8DA9S8Asc8ca9sud0c0sgh.123.some-key
**** IMPORTANTE ****
Os decorator são processados antes da instanciação dos módulos e,
portanto, serviços injetados e providers não estão disponíveis.
Se precisar de variáveis de ambiente para compor a chave do cache,
é necessário utilizar o o acesso através da classe de configuração
`NclabsConfig.load()`.
Contexto
// app.controller.ts
// app.service.ts
...
@Controller()
...
youMethod(@NclabsCtx() context: NclabsContext) {
const { meta, headers, params, data } = context;
// meta: Informações do microserviço
// headers: Header do request
// params: Path parameters do request
// data: Request (Body and Query parameters)
return;
}
...
👉 context.params
somente terá valores nas requisições HTTP. Levar em consideração as possíveis chamadas RPC.
Client Service
// app.controller.ts
// app.service.ts
...
@Controller()
// ou
@Injectable()
...
constructor(
private readonly clientRpc: NclabsRpcClientService,
) {}
...
/**
* CALL - Observable Approach
*/
yourMethod(@NclabsCtx() context: NclabsContext): Observable<Person> {
const payload = {
name: context.data.name
};
return this.clientRpc.call('other-service.action', payload, context);
}
/**
* CALL- Promise Approach
*/
async yourAsyncMethod(@NclabsCtx() context: NclabsContext): Promise<Person> {
const payload = {
name: context.data.name
};
const person = await this.clientRpc.callAsync('person.create', payload, context);
// do something
return person;
}
/**
* CALL with event emitter
*/
otherMethod(@NclabsCtx() context: NclabsContext): Observable<Person> {
const payload = {
name: context.data.name
};
return this.clientRpc.call('person.create', payload, context).pipe(
// Emit event
tap((data: Person) => this.clientRpc.emit('person-created', data)),
);
}
...
Exceptions
AS requisições REST e chamadas de serviço (...client.call
) abstraem a normalização do objeto de exceções.
Quando for necessário lançar exceções manualmente, utilizar a sintaxe abaixo:
// app.controller.ts
// app.service.ts
...
@Controller()
// ou
@Injectable()
...
/**
*
* Generate password for G5
*
*/
private _generateEncryptPassword(username: string): string {
// create/get password
if (!password || password === 'null') {
const error = {
code: 401,
type: 'UNAUTHORIZED',
message: 'Não foi possível gerar a senha encriptada do Senior G5',
error: {
jar: 'crypt.jar',
encrypt: 'CBC',
user: username,
date: dt.toLocaleString('pt-BR', options).replace(',', ''),
},
};
throw new RpcException(error);
}
// do something
return encryptedPassword;
}
...