Skip to content

Commit

Permalink
feat: add basic nats rpc
Browse files Browse the repository at this point in the history
  • Loading branch information
temarusanov committed Jul 2, 2023
1 parent d76144e commit 0948826
Show file tree
Hide file tree
Showing 30 changed files with 719 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
PORT=3000
GATEWAY_PORT=3052
GATEWAY_SUBGRAPHS='[{"name": "api", "url": "http://localhost:3000/graphql"}]'

NATS_URL=nats://localhost:4222
SAMPLE_DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres?schema=public
4 changes: 4 additions & 0 deletions apps/api/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ApolloFederationDriver,
ApolloFederationDriverConfig,
} from '@nestjs/apollo'
import { NatsModule } from 'core/nats'

@Module({
imports: [
Expand All @@ -30,6 +31,9 @@ import {
maxQueryExecutionTime: 5000,
},
}),
NatsModule.forRoot({
servers: env.get('NATS_URL').required().asString(),
}),
],
controllers: [],
providers: [],
Expand Down
18 changes: 18 additions & 0 deletions libs/core/common/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
11 changes: 11 additions & 0 deletions libs/core/common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# common

This library was generated with [Nx](https://nx.dev).

## Building

Run `nx build common` to build the library.

## Running unit tests

Run `nx test common` to execute the unit tests via [Jest](https://jestjs.io).
14 changes: 14 additions & 0 deletions libs/core/common/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable */
export default {
displayName: 'common',
preset: '../../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': [
'ts-jest',
{ tsconfig: '<rootDir>/tsconfig.spec.json' },
],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../../coverage/libs/core/common',
}
30 changes: 30 additions & 0 deletions libs/core/common/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "common",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/core/common/src",
"projectType": "library",
"targets": {
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["libs/core/common/**/*.ts"]
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/core/common/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
}
},
"tags": []
}
2 changes: 2 additions & 0 deletions libs/core/common/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './lib/errors/common-errors.enum'
export * from './lib/errors/common.error'
21 changes: 21 additions & 0 deletions libs/core/common/src/lib/errors/common-errors.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export enum CommonErrorsEnum {
Error = 'ERROR-000',
NotFound = 'ERROR-001',
Forbidden = 'ERROR-002',
UnexpectedError = 'ERROR-003',
ValidationError = 'ERROR-004',
UniqueError = 'ERROR-005',
RequestError = 'ERROR-006',
UnauthorizedError = 'ERROR-007',
}

export const COMMON_ERROR_TITLES = {
[CommonErrorsEnum.Error]: 'Error',
[CommonErrorsEnum.NotFound]: 'Not found',
[CommonErrorsEnum.Forbidden]: 'Forbidden',
[CommonErrorsEnum.UnexpectedError]: 'Unexpected error',
[CommonErrorsEnum.ValidationError]: 'Validation error',
[CommonErrorsEnum.UniqueError]: 'Unique error',
[CommonErrorsEnum.RequestError]: 'Request error',
[CommonErrorsEnum.UnauthorizedError]: 'Unauthorized',
}
28 changes: 28 additions & 0 deletions libs/core/common/src/lib/errors/common.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { COMMON_ERROR_TITLES, CommonErrorsEnum } from './common-errors.enum'

export class CommonError<
T extends string = CommonErrorsEnum,
M = Record<string, string>,
> extends Error {
code: T
metadata?: M

constructor(
code: T,
message?: { [code: string]: string } | string,
metadata?: M,
) {
super(
message === undefined
? COMMON_ERROR_TITLES[
(code as string) ||
COMMON_ERROR_TITLES[CommonErrorsEnum.Error]
]
: typeof message === 'string'
? message
: message[code],
)
this.code = code
this.metadata = metadata
}
}
16 changes: 16 additions & 0 deletions libs/core/common/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs"
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
11 changes: 11 additions & 0 deletions libs/core/common/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"declaration": true,
"types": ["node"],
"target": "es6"
},
"include": ["src/**/*.ts"],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}
14 changes: 14 additions & 0 deletions libs/core/common/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
18 changes: 18 additions & 0 deletions libs/core/nats/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
11 changes: 11 additions & 0 deletions libs/core/nats/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# nats

This library was generated with [Nx](https://nx.dev).

## Building

Run `nx build nats` to build the library.

## Running unit tests

Run `nx test nats` to execute the unit tests via [Jest](https://jestjs.io).
14 changes: 14 additions & 0 deletions libs/core/nats/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable */
export default {
displayName: 'nats',
preset: '../../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': [
'ts-jest',
{ tsconfig: '<rootDir>/tsconfig.spec.json' },
],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../../coverage/libs/core/nats',
}
30 changes: 30 additions & 0 deletions libs/core/nats/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "nats",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/core/nats/src",
"projectType": "library",
"targets": {
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["libs/core/nats/**/*.ts"]
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/core/nats/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
}
},
"tags": []
}
2 changes: 2 additions & 0 deletions libs/core/nats/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './lib/nats-configs/nats-module.config'
export * from './lib/nats.module'
32 changes: 32 additions & 0 deletions libs/core/nats/src/lib/nats-configs/nats-module.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ConfigurableModuleBuilder } from '@nestjs/common'
import { merge } from 'lodash'
import { ConnectionOptions } from 'nats'

export interface NatsConfig extends ConnectionOptions {
temp?: false
}

export const DEFAULT_NATS_CONFIG: Pick<NatsConfig, 'temp'> = {
temp: false,
}

export function patchNatsConfig(
config: Pick<typeof NATS_OPTIONS_TYPE, keyof typeof DEFAULT_NATS_CONFIG>,
) {
if (config) {
Object.assign(
config,
merge(DEFAULT_NATS_CONFIG, config),
) as typeof NATS_OPTIONS_TYPE
}
return config
}

export const {
ConfigurableModuleClass: NatsConfigurableModuleClass,
MODULE_OPTIONS_TOKEN: NATS_CONFIG,
ASYNC_OPTIONS_TYPE: NATS_ASYNC_OPTIONS_TYPE,
OPTIONS_TYPE: NATS_OPTIONS_TYPE,
} = new ConfigurableModuleBuilder<NatsConfig, 'forRoot'>({
optionsInjectionToken: `NATS_CONFIG`,
}).build()
9 changes: 9 additions & 0 deletions libs/core/nats/src/lib/nats-errors/nats-errors.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export enum NatsErrorsEnum {
Timeout = 'NATS-000',
NoResponders = 'NATS-001',
}

export const NATS_ERROR_TITLES = {
[NatsErrorsEnum.Timeout]: `Someone is listening but didn't respond`,
[NatsErrorsEnum.NoResponders]: `No one is listening to this request`,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Injectable } from '@nestjs/common'
import { HealthIndicator, HealthIndicatorResult } from 'core/health-checks'
import { NatsConnectionService } from '../nats-services/nats-connection.service'

@Injectable()
export class NatsConnectionHealthIndicator implements HealthIndicator {
name = 'nats'

constructor(private readonly natsConnection: NatsConnectionService) {}

async isHealthy(): Promise<HealthIndicatorResult> {
try {
const status = this.natsConnection.status()

if (status.connected) {
return {
name: this.name,
status: 'up',
}
}

return {
name: this.name,
status: 'down',
error: status.error,
}
} catch (error) {
return {
name: this.name,
status: 'down',
error: error.message,
}
}
}
}
14 changes: 14 additions & 0 deletions libs/core/nats/src/lib/nats-interfaces/nats.interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { MsgHdrs, RequestOptions as NatsRequestOptions } from 'nats'

export interface NatsResponse<T> {
subject: string
data?: T
headers?: MsgHdrs
}

export interface RequestOptions
extends Omit<NatsRequestOptions, 'headers' | 'timeout'> {
timeout?: number
// eslint-disable-next-line @typescript-eslint/no-explicit-any
headers: Record<string, string>
}
Loading

0 comments on commit 0948826

Please sign in to comment.