Nest: [Feature] NestJS Route Exporter

Created on 24 Jul 2020  路  6Comments  路  Source: nestjs/nest

Feature Request

NestJS Route exporter

Is your feature request related to a problem? Please describe.


While developing SPA's or any other REST dependent app there is common challenge for developers how to share routes from server/service to applications.

Describe the solution you'd like


I've created workable version of route exporter for NestJS by traversing all controllers/routes and exporting them to dev specified directory file. Exported file can be typescript or javascript it depending on what developer wants. If it's typescript file then it's fully typehinted. If it's javascript it's just pure javascript file.

After exporting routes file, developers can push them to some repository and use them as API interface for their applications.

I'd like to create same route-exporter module for NestJS and solve this common challenge.

So here are few examples how it should work:

import { routeExporter } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  /**
   * app       | Used for traversing app controllers
   * baseUri   | Used as baseUri - Optional we can set baseUri from app by default
   * directory | Used as directory where routes will be exported - Optional we can define default dir to be exported
   * file      | Filename and file-type (ts,js) that will be exported in <root>/directory/fileName.{ts/js} - Optional we can define default filename to be exported
   */
  routeExporter(app);

  // Or 
  routeExporter(app, 'http://localhost:3001', 'common', 'api.ts');

  // Or
  routeExporter(app, {
    baseUri: 'http://localhost:3001',
    output: 'common/api.ts'
  });

  // Use _includes_ to specify from which controllers to export routes
  routeExporter(app, {
    baseUri: 'http://localhost:3001',
    output: 'common/api.ts',
    includes: [
      HelloController,
    ],
  });

  // Use normalize to normalize exported const name.
  routeExporter(app, {
    baseUri: 'http://localhost:3001',
    output: 'common/api.ts',
    normalize: (controllerName: string): string => {
      return controllerName.replace('Controller', 'Endpoints')
    },
  });


  await app.listen(3000);
}

bootstrap();

So if we have let's say HeaderController the output for api.ts file would be:

Typescript

If we wanna export api.js and have HeaderController in our app the output for api.js file would be:

Javascript

@kamilmysliwiec What do you think ? I'd like to create PR for this one.

Thanks!

needs triage type

Most helpful comment

Hi @jmcdo29

There are multiple OpenAPI files generator libraries, the main difference here is that in essence OpenAPI generates specifications for developers that helps them understand and interact with existing API's on OpenAPI platform that are specified in swagger files, on the other side there are multiple pros using route-exporter. Here are some of them:

  • Developers define routeExporter on one place that exports them. (Exporting params can be dynamic if service is pipelined with some deploy system, or using .env files/process.env or anything else...)
  • REST endpoint signatures are changed and expanded while developing REST app (this is most important) They will not waste time on changing their request PATHS or request METHODS on apps if they are changed on NestJS side while developing.
  • Exported routes can be used as git repository, or manipulate with exported output through some build pipeline that will deliver routes to their apps.
  • The more they define dev friendly controller endpoint methods, the more they will have dev friendly interface on their apps.
  • IDE's will be happy with output file/files.
  • Developers will be happy with autocomplete and simplicity of usage.
  • They will consume them in their applications (there is nice interface proposal) with all required request props (PATH, METHOD). Property name that contains PATH & METHOD can be interpreted as ALIAS. For example the usage with _fetch_ api would be:.
import { Api: { HEADER: { create } } } from 'src/api'; // This can be git repo or delivered through build pipeline. 

fetch(create.path, { method: create.method }).then(json);

This can be extended more:

  • Support method alias normalizing on runtime.
  • Support controller alias normalizing on runtime.
  • Support controller including.
  • Support controller excluding.
  • Use decorators in controllers instead of API proposed above.
  • Use some interface in modules instead of API proposed above.

What should be done if this is considered as "Nice to have".

  • Agree what would be best interface on NestJS side.
  • Exclude route exported directory/directories from compiler pass since they are generated and watched.

All 6 comments

This seems interesting. What's the main difference between this and something like OpenAPI with choice generators to create calls from swagger files?

Hi @jmcdo29

There are multiple OpenAPI files generator libraries, the main difference here is that in essence OpenAPI generates specifications for developers that helps them understand and interact with existing API's on OpenAPI platform that are specified in swagger files, on the other side there are multiple pros using route-exporter. Here are some of them:

  • Developers define routeExporter on one place that exports them. (Exporting params can be dynamic if service is pipelined with some deploy system, or using .env files/process.env or anything else...)
  • REST endpoint signatures are changed and expanded while developing REST app (this is most important) They will not waste time on changing their request PATHS or request METHODS on apps if they are changed on NestJS side while developing.
  • Exported routes can be used as git repository, or manipulate with exported output through some build pipeline that will deliver routes to their apps.
  • The more they define dev friendly controller endpoint methods, the more they will have dev friendly interface on their apps.
  • IDE's will be happy with output file/files.
  • Developers will be happy with autocomplete and simplicity of usage.
  • They will consume them in their applications (there is nice interface proposal) with all required request props (PATH, METHOD). Property name that contains PATH & METHOD can be interpreted as ALIAS. For example the usage with _fetch_ api would be:.
import { Api: { HEADER: { create } } } from 'src/api'; // This can be git repo or delivered through build pipeline. 

fetch(create.path, { method: create.method }).then(json);

This can be extended more:

  • Support method alias normalizing on runtime.
  • Support controller alias normalizing on runtime.
  • Support controller including.
  • Support controller excluding.
  • Use decorators in controllers instead of API proposed above.
  • Use some interface in modules instead of API proposed above.

What should be done if this is considered as "Nice to have".

  • Agree what would be best interface on NestJS side.
  • Exclude route exported directory/directories from compiler pass since they are generated and watched.

Are there any leads from this? Are we going to implement this at some-point in the future, is it stale :confused:

Thanks for bringing this back up. I think this looks really cool, and I could see it being pretty useful. My concern is adding it to the main codebase as it may not be for everyone, but I could see it being a nice library to publish so it's an opt in kind of thing, just like swagger already is.

Does this require any of Nest's internals, or is it mainly getting the http engine (does this work for Fastify and Express?) and look at the router that's created?

@YashKumarVerma

Thanks from my side for bringing it up also.

I'm going to create a PR for this one with implementation and API and then we can discuss more? :)

Like I said, rather than adding this to @nestjs/common or @nestjs/core, I could see this itself being a library on its own. Maybe it's not as easy due to missing how it's implemented, but I'm not sure why we'd want to bring this into these packages

Was this page helpful?
0 / 5 - 0 ratings

Related issues

artaommahe picture artaommahe  路  3Comments

thohoh picture thohoh  路  3Comments

mishelashala picture mishelashala  路  3Comments

JulianBiermann picture JulianBiermann  路  3Comments

marshall007 picture marshall007  路  3Comments