{"id":19623630,"url":"https://github.com/flowcore-io/library-flowcore-microservice-ts","last_synced_at":"2025-04-28T05:30:28.246Z","repository":{"id":65219409,"uuid":"579011648","full_name":"flowcore-io/library-flowcore-microservice-ts","owner":"flowcore-io","description":"The flowcore microservice library is designed to provide strong opinions on how to handle configuration, logging, health checks, metrics, and observability. ","archived":false,"fork":false,"pushed_at":"2024-01-22T15:50:07.000Z","size":493,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-01T14:40:45.684Z","etag":null,"topics":["microservice","nestjs","typescript"],"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/flowcore-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-12-16T12:45:06.000Z","updated_at":"2024-05-16T13:40:18.000Z","dependencies_parsed_at":"2024-01-22T17:45:34.176Z","dependency_job_id":"54286e7c-2a5b-4a80-bd67-6fa0ca1c7ff9","html_url":"https://github.com/flowcore-io/library-flowcore-microservice-ts","commit_stats":{"total_commits":52,"total_committers":4,"mean_commits":13.0,"dds":"0.40384615384615385","last_synced_commit":"cec35147b09db6baeb8792cf7e7626e9f5c9e11e"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Flibrary-flowcore-microservice-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Flibrary-flowcore-microservice-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Flibrary-flowcore-microservice-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Flibrary-flowcore-microservice-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flowcore-io","download_url":"https://codeload.github.com/flowcore-io/library-flowcore-microservice-ts/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224096381,"owners_count":17255077,"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":["microservice","nestjs","typescript"],"created_at":"2024-11-11T11:34:57.601Z","updated_at":"2024-11-11T11:34:58.946Z","avatar_url":"https://github.com/flowcore-io.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Build](https://github.com/flowcore-io/library-flowcore-microservice-ts/actions/workflows/publish.yml/badge.svg)\n\n# Flowcore Microservice\n\nThe flowcore microservice library is designed to provide strong opinions on how to handle configuration, logging, health\nchecks, metrics, and\nobservability. It provides a set of modules that allow you to quickly set up services.\n\nThe library is particularly well-suited for use in microservice architectures, where it can help you\nquickly and easily set up the essential components of configuration, logging, health checks, metrics, and observability.\n\n## Installation\n\ninstall with npm:\n\n```bash\nnpm install @flowcore/microservice @nestjs/core @nestjs/common @nestjs/terminus\n```\n\nor yarn:\n\n```bash\nyarn add @flowcore/microservice @nestjs/core @nestjs/common @nestjs/terminus\n```\n\n## Usage\n\nThe library provides a set of modules that allow you to quickly set up services. The modules are:\n\n- [Configuration](#configuration)\n- [Logging](#logging)\n- [Health](#health)\n- [Metrics](#metrics)\n- [Observability](#observability)\n\n### Configuration\n\nThe configuration library uses zod to validate the configuration. It provides a set of primitives that can be used to\ncreate configuration schemas. The library also provides a configuration Module that can load and validate configuration\nfrom environment variables.\n\nTo use the module first create a configuration schema.\n\n```typescript\n// config file\nimport {z} from \"zod\";\nimport {ConfigurationSchema} from \"@flowcore/microservice\";\n\nexport const SomeConfigurationShape = z.object({\n  someKey: z.string(),\n});\nexport type SomeConfiguration = z.infer\u003ctypeof SomeConfigurationShape\u003e;\n\nexport class SomeConfigurationSchema extends ConfigurationSchema {\n  context = \"some-context\";\n  linking = {\n    someKey: {\n      env: \"SOME_KEY\",\n      default: \"some-default-value\", // optional, only if you want to override the default value when loading the schema\n    },\n  };\n  shape = SomeConfigurationShape;\n\n  // this is optinal, but can be used to override the defaults specified in the linking\n  constructor(overrideDefaults?: { [key: string]: any }) {\n    super();\n    ConfigurationSchema.override(this.linking, overrideDefaults);\n  }\n}\n\n```\n\n\u003e **NB!** If you want to be able to override the default of a configuration value you can use the `ConfigurationSchema`\n\u003e class to set the default, not the `zod` schema and include the constructor specified above.\n\nthen create a module builder that uses the configuration schema.\n\n```typescript\n// module builder\nimport {SomeModule} from \"./some.module\";\nimport {BaseBuilder, ConfigService} from \"@flowcore/microservice\";\n\nexport class SomeModuleBuilder extends BaseBuilder {\n  requiredContext = [\"some-context\"];\n\n  override build() {\n    super.build();\n\n    if (!this.config) {\n      throw new Error(`Missing config for ${this.constructor.name}`);\n    }\n\n    return SomeModule.registerAsync({\n      imports: [this.config],\n      inject: [ConfigService],\n      useFactory: (config: ConfigService\u003cSomeConfiguration\u003e) =\u003e ({\n        someKey: config.schema.someKey,\n      }),\n    });\n  }\n}\n```\n\n\u003e **requiredContext** is used when you want the configuration to be required. If the configuration is not provided the\n\u003e module will throw an error.\n\nThen to use the builder and configuration in your service.\n\n```typescript\n// app module\nimport {Module} from \"@nestjs/common\";\nimport {SomeModuleBuilder} from \"./some-builder\";\nimport {SomeConfigurationSchema} from \"./some-config\";\nimport {\n  ConfigFactory,\n  ConfigModule,\n} from \"@flowcore/microservice\";\n\nconst config = ConfigModule.forRoot(\n  new ConfigFactory()\n    // ... other schemas\n    .withSchema(SomeConfigurationSchema, /* optional override defaults { path-to-key: new default value, } */)\n  // ... other schemas\n);\n\n@Module({\n  imports: [\n    config,\n    // ... other modules\n    new SomeModuleBuilder().withConfig(config).build(),\n    // ... other modules\n  ],\n  controllers: [],\n  providers: [],\n})\nexport class AppModule {\n}\n\n```\n\nThe configuration module has a `DefaultAppConfigurationSchema` that will be applied unless explicitly set to false. The\ndefault configuration schema will load the following environment variables:\n\n- `PORT` - the port the service will listen on for http endpoints, for example /health and /metrics (default: 3000)\n\n\u003e this is exported as the `DefaultAppConfiguration` interface in the `@flowcore/microservice` package. And can be used\n\u003e when accessing the configuration through `useFactory`.\n\n### Logging\n\nThe logging library uses `winston` and `nest-winston` to provide logging. It provides configuration and injection\nmechanics for the winston logger.\n\nTo use the module load the configuration schema into the configuration factory and import the logging module using the\nbuilder.\n\n```typescript\n// app module\nimport {Module} from \"@nestjs/common\";\nimport {\n  ConfigFactory,\n  ConfigModule,\n  LoggerModuleBuilder,\n  LoggerModuleConfigurationSchema,\n} from \"@flowcore/microservice\";\n\nconst config = ConfigModule.forRoot(\n  new ConfigFactory()\n    // ... other schemas\n    .withSchema(LoggerModuleConfigurationSchema),\n  // ... other schemas\n);\n\n@Module({\n  imports: [\n    config,\n    // ... other modules\n    new LoggerModuleBuilder().withConfig(config).build(),\n    // ... other modules\n  ],\n  controllers: [],\n  providers: [],\n})\nexport class AppModule {\n}\n\n```\n\nthe logging module will load the following environment variables:\n\n- `LOG_LEVEL` - the log level to use for the logger (default: info)\n- `LOG_PRETTY_PRINT` - whether to pretty print the logs (default: false)\n- `LOG_USE_LABELS` - whether to use labels in the logs (default: false)\n\n\u003e this is exported as the `LoggerModuleConfiguration` interface in the `@flowcore/microservice` package. And can be used\n\u003e when accessing the configuration through `useFactory`.\n\n### Health\n\nThe health module uses `@nestjs/terminus` to provide health checks. It provides decorator that can be used to collect\nhealth checks.\n\nto use the module, first create a health controller.\n\n```typescript\n// health controller\nimport {Controller, Get} from \"@nestjs/common\";\nimport {HealthCheck, HealthCheckResult} from \"@nestjs/terminus\";\nimport {HealthService} from \"@flowcore/microservice\";\n\n@Controller(\"health\")\nexport class HealthController {\n  constructor(private health: HealthService) {\n  }\n\n  @Get()\n  @HealthCheck()\n  async check(): Promise\u003cHealthCheckResult\u003e {\n    return this.health.check();\n  }\n}\n\n```\n\n\u003e Remember to add an access decorator to the health check endpoint if you are using authentication in your application.\n\nThen import it and the `HealthModule` into your application module.\n\n```typescript\n// app module\nimport {Module} from \"@nestjs/common\";\nimport {\n  ConfigFactory,\n  ConfigModule,\n  HealthModuleBuilder,\n} from \"@flowcore/microservice\";\nimport {HealthController} from \"./health.controller\";\n\n@Module({\n  imports: [\n    new HealthModuleBuilder().usingController(HealthController).build(),\n  ],\n  controllers: [],\n  providers: [],\n})\nexport class AppModule {\n}\n```\n\nThen to add health checks to the service, use the `@HealthCheckIndicator` decorator.\n\n```typescript\n// some health check\nimport {HealthCheckIndicator, CheckHealth} from \"@flowcore/microservice\";\nimport {Injectable} from \"@nestjs/common\";\nimport {HealthIndicator, HealthIndicatorResult} from \"@nestjs/terminus\";\n\n@Injectable()\n@HealthCheckIndicator()\nclass HealthyService extends HealthIndicator implements CheckHealth {\n  async isHealthy(): Promise\u003cHealthIndicatorResult\u003e {\n    // do some health check logic\n    return this.getStatus(/* some key */, /* true or false */);\n  }\n}\n```\n\n\u003e Remember to add the `HealthModule` to the module imports.\n\n### Metrics\n\nThe metrics module is a wrapper around `@willsoto/nestjs-prometheus` to provide metrics for the service. It provides a\nmodule that can be configured and imported into the application module.\n\nTo use the module, first create a metrics controller.\n\n```typescript\n// metrics controller\nimport {Controller, Get, Res} from \"@nestjs/common\";\nimport {PrometheusController} from \"@flowcore/microservice\";\nimport {Response} from \"express\";\n\n@Controller()\nexport class MetricsController extends PrometheusController {\n  @Get()\n  async index(@Res() response: Response) {\n    return super.index(response);\n  }\n}\n```\n\nThen import it and the `MetricsModule` into your application module using the builder.\n\n```typescript\n// app module\nimport {Module} from \"@nestjs/common\";\nimport {MetricsController} from \"./metrics.controller\";\nimport {MetricsModuleBuilder} from \"@flowcore/microservice\";\n\n@Module({\n  imports: [\n    // ... other modules\n    new MetricsModuleBuilder().usingController(MetricsController).build()\n    // ... other modules\n  ],\n  controllers: [],\n  providers: [],\n})\nexport class AppModule {\n}\n```\n\nto use the metrics module, follow the instructions in\nthe [`@willsoto/nestjs-prometheus`](https://www.npmjs.com/package/@willsoto/nestjs-prometheus) package.\n\n\u003e The `createCounterProvider` and the `Counter` class are exported from the `@flowcore/microservice` package, same goes\n\u003e for `Gauge`,`Histogram` and`Summary`. So you can import them from there instead of the `@willsoto/nestjs-prometheus`\n\u003e and `prom-client` packages.\n\nTo use default node metrics exported from the `@willsoto/nestjs-prometheus` package, use the `withDefaultMetrics` method\nwhen building the metrics module.\n\nTo add default labels to all metrics, use the `withDefaultLabels` method when building the metrics module.\n\n### Observability (Deprecated)\n\nthe observability module has been marked as deprecated, and will be implemented in a new version using Open Telemetry. For now, traces are implemented using eBPF from Groundcover.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowcore-io%2Flibrary-flowcore-microservice-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflowcore-io%2Flibrary-flowcore-microservice-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowcore-io%2Flibrary-flowcore-microservice-ts/lists"}