Fcmam5 / fastify-route-constraints-poc

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Description

A PoC for nest#12567

PoC

Install dependencies

pnpm i

# install local copy of updated package e.g.
pnpm i /Users/fcmam5/lab/oss/nest/packages/platform-fastify

Run server with pnpm start:dev

we see that the constraints are set correctly.
[Nest] 73676  - 10/14/2023, 4:20:17 PM     LOG [NestFactory] Starting Nest application...
[Nest] 73676  - 10/14/2023, 4:20:17 PM     LOG [InstanceLoader] AppModule dependencies initialized +16ms
[Nest] 73676  - 10/14/2023, 4:20:17 PM     LOG [RoutesResolver] AppController {/}: +3ms
{ hasConstraints: false }
{ routeConstraints: undefined }
[Nest] 73676  - 10/14/2023, 4:20:17 PM     LOG [RouterExplorer] Mapped {/greet, GET} (version: v1) route +7ms
{ hasConstraints: true }
{ routeConstraints: { version: 'v2' } }
[Nest] 73676  - 10/14/2023, 4:20:17 PM     LOG [RouterExplorer] Mapped {/greet, GET} route +2ms
{ hasConstraints: true }
{ routeConstraints: { host: 'de.example.com' } }
[Nest] 73676  - 10/14/2023, 4:20:17 PM     LOG [RouterExplorer] Mapped {/greet, GET} (version: v3) route +1ms
{ hasConstraints: true }
{ routeConstraints: { host: 'ar.example.com' } }
[Nest] 73676  - 10/14/2023, 4:20:17 PM     LOG [RouterExplorer] Mapped {/greet, GET} route +2ms
[Nest] 73676  - 10/14/2023, 4:20:17 PM     LOG [NestApplication] Nest application successfully started +2ms

The objects are logging the two objects from this block, with:

    console.log({ hasConstraints });
    console.log({ routeConstraints });

Testing the implementation

Check app.controller.ts:

import { Controller, Get, Req, Version } from '@nestjs/common';
import { RouteConfig, RouteConstraints } from '@nestjs/platform-fastify';

@Controller()
export class AppController {
  // Using NestJS API versioning: https://docs.nestjs.com/techniques/versioning
  @Get('/greet')
  @Version('v1')
  @RouteConfig({ output: 'Hello world!' })
  greetV1(@Req() req) {
    return { msg: req.routeOptions.config.output, version: 'v1' };
  }

  // Using Fastify version constraints: https://fastify.dev/docs/latest/Reference/Routes/#version-constraints
  @Get('/greet')
  @RouteConstraints({
    version: 'v2',
  })
  greetV2(@Req() req) {
    return { msg: 'HELLO WORLD!', version: 'v2' };
  }

  // Using NestJS API versioning and Fastify host constraints: https://fastify.dev/docs/latest/Reference/Routes/#host-constraints
  @Get('/greet')
  @Version('v3')
  @RouteConstraints({
    host: 'de.example.com',
  })
  greetDEHosts() {
    return { msg: 'Hello welt!', version: 'v3' };
  }

  // Using Fastify host constraints: https://fastify.dev/docs/latest/Reference/Routes/#host-constraints
  @Get('/greet')
  @RouteConstraints({
    host: 'ar.example.com',
  })
  greetArHosts() {
    return { msg: 'آهلا بالعالم' };
  }

  // Not using any config
  @Get('/greet-everyone')
  greetEveryone() {
    return { msg: 'Hello world!' };
  }
}

It maps multiple handlers for GET /greet each one of them doesn't have any constraints.

For this example, I'm using header versioning with:

  app.enableVersioning({
    type: VersioningType.HEADER,
    header: 'Accept-Version',
  })

And below are the tests using HTTPie client:


When not using any configurations

Request:

▶ http http://127.0.0.1:3000/greet-everyone  
HTTP/1.1 200 OK
Connection: keep-alive
Date: Sat, 14 Oct 2023 14:43:36 GMT
Keep-Alive: timeout=72
content-length: 22
content-type: application/json; charset=utf-8

{
    "msg": "Hello world!"
}

This hits:

  @Get('/greet-everyone')
  greetEveryone() {
    return { msg: 'Hello world!' };
  }

Using NestJS API versioning

Request:

▶ http http://127.0.0.1:3000/greet "Accept-Version:v1"                       
HTTP/1.1 200 OK
Connection: keep-alive
Date: Sat, 14 Oct 2023 14:50:19 GMT
Keep-Alive: timeout=72
content-length: 37
content-type: application/json; charset=utf-8

{
    "msg": "Hello world!",
    "version": "v1"
}

This hits:

  @Get('/greet')
  @Version('v1')
  @RouteConfig({ output: 'Hello world!' })
  greetV1(@Req() req) {
    return { msg: req.routeOptions.config.output, version: 'v1' };
  }

Don't mind @RouteConfig({ output: 'Hello world!' }) It's just there to test that this change isn't breaking @RouteConfig 😁


Using Fastify version constraints

Request

▶ http http://127.0.0.1:3000/greet "Accept-Version:v2"
HTTP/1.1 200 OK
Connection: keep-alive
Date: Sat, 14 Oct 2023 14:54:23 GMT
Keep-Alive: timeout=72
content-length: 37
content-type: application/json; charset=utf-8

{
    "msg": "HELLO WORLD!",
    "version": "v2"
}

This hits:

  @Get('/greet')
  @RouteConstraints({
    version: 'v2',
  })
  greetV2(@Req() req) {
    return { msg: 'HELLO WORLD!', version: 'v2' };
  }

Using Fastify host constraints

Request:

▶ http http://127.0.0.1:3000/greet "Host: ar.example.com"                    
HTTP/1.1 200 OK
Connection: keep-alive
Date: Sat, 14 Oct 2023 14:58:23 GMT
Keep-Alive: timeout=72
content-length: 33
content-type: application/json; charset=utf-8

{
    "msg": "آهلا بالعالم"
}

This hits:

  @Get('/greet')
  @RouteConstraints({
    host: 'ar.example.com',
  })
  greetArHosts() {
    return { msg: 'آهلا بالعالم' };
  }

Using NestJS API versioning and Fastify host constraints

Request:

▶ http http://127.0.0.1:3000/greet "Accept-Version:v3" "Host: de.example.com"
HTTP/1.1 200 OK
Connection: keep-alive
Date: Sat, 14 Oct 2023 14:56:33 GMT
Keep-Alive: timeout=72
content-length: 36
content-type: application/json; charset=utf-8

{
    "msg": "Hello welt!",
    "version": "v3"
}

This hits:

  @Get('/greet')
  @Version('v3')
  @RouteConstraints({
    host: 'de.example.com',
  })
  greetDEHosts() {
    return { msg: 'Hello welt!', version: 'v3' };
  }

License

Nest is MIT licensed.

About

License:MIT License


Languages

Language:TypeScript 76.4%Language:JavaScript 23.6%