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/rpc-module
Configuração
Carrega o arquivo de configuração (ex.: docker-compose.env) compartilhado entre todos os serviços e disponibiliza
uma biblioteca de configuração com os valores de ambientes do serviço.
-
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-nclabs-rpc-module/blob/main/config.md
Variável de ambiente setada no docker-compose.yml:
environment:
SERVICE_NAME: <your-service-name>
Modulo
...
import { NclabsRpcModule } from '@nclabs/rpc-module';
@Module({
imports: [
NclabsRpcModule.register({ cache: true }),
],
})
export class AppModule {}
Recursos
NclabsConfig | Lib | * | Disponibiliza todas as váriaveis de ambiente |
NclabsAction | Decorator | Controller | Configura requisições RPC e HTTP (opcional) |
NclabsEvent | Decorator | Controller | Configura envio de eventos RPC |
NclabsCtx | Decorator | Controller Service | 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 |
NclabsRxjsErrorHandler | Lib | Observable Approach | Trata exceções do microserviço (catchError) |
NclabsException | Lib | Promise Approach | Trata exceções do microserviço |
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
...
@Controller()
export class AppController {
...
@NclabsAction({
name: 'your-action-name',
rest: {
methods: ['GET', 'POST'],
path: '/your-path',
},
cache: {
keys: ['#headers.authorization', '#params.id', 'some-key'],
ttl: 1200,
},
})
youMethodName(@NclabsCtx() context: NclabsContext) {
return;
}
...
-
CACHE: A configuração cache
irá disponibilizar um cache para o retorno da requisição com as chaves especificadas no keys
e com o TTL especificado no ttl
.
A chave do cache será criada concatenando:
1. PATTERN = <SERVICE_NAME.name> ou <SERVICE_NAME.method.path>
2. authorization = informação do header `authorization`
3. id = atributo `id` do objeto `data` do contexto
4. some-key = texto estático
key: PATTERN.Bearer A8DA9S8C9Asc098ca9s0ud0c0sgh.123.some-key
**** IMPORTANTE ****
Os decorator são processados antes da instanciação dos módulos e,
portanto, o ConfigService não está carregado.
Caso for utilizar variáveis de ambiente nas configurações, é
necessário buscar o valor utilizando process.env.VARIABLE.
Contexto
...
@Controller()
@Injectable()
...
youMethod(@NclabsCtx() context: NclabsContext) {
const { meta, headers, data } = context;
return;
}
...
Client Service
...
@Controller()
@Injectable()
...
constructor(
private readonly clientRpc: NclabsRpcClientService,
) {}
...
youMethod(@NclabsCtx() context: NclabsContext): Obserable<Person> {
const payload = {
name: 'John'
};
return this.clientRpc.call('other-service.action', payload, context);
}
...
Exceptions
...
@Controller()
@Injectable()
...
youMethod(token: string, includeG5 = false): Observable<IUser> {
const url = `${baseUrl}platform/user/queries/getUser`;
const headers = {
Authorization: `Bearer ${token}`,
};
return this.httpService.get<IUser>(url, { headers }).pipe(
map((response: AxiosResponse<IUser>) => response.data),
map((data: IUser) => ({ ...data, authentication: `Bearer ${token}` })),
map(this._mapResponseToIUser),
map((user: IUser) => {
if (includeG5) {
const password = this._generateEncryptPassword(user.username);
user.password = password;
user.encryption = 2;
}
return user;
}),
catchError(NclabsRxjsErrorHandler),
);
}
private _generateEncryptPassword(username: string): string {
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 NclabsException(error);
}
return encryptedPassword;
}
...