Formulaic Docs

Usage

With FPInterceptor installed as a Nest interceptor, you can return FP objects in your controllers.

import { DatabaseException, oneOfFP } from "@formulaic/fp";
import { Controller } from "@nestjs/common";
import { ApiExtraModels, ApiTags, ApiOkResponse } from "@nestjs/swagger";
import { UserService } from "./user.service";
import { UserDetails } from "./dto/user-response"; (1)

@Controller("user")
@ApiTags("users")
@ApiExtraModels( (2)
  MissingPermission,
  NotFound,
  UserDetails,
  DatabaseException
)
export class UserController {

  public constructor(
    private readonly users: UserService, (3)
  ) {}

  @Get(":userId")
  @ApiOkResponse(oneOfFP([
    NotFound,
    UserDetails,
    DatabaseException,
  ]))
  public async userDetails(
    @Param("userId") userId: string,
  ): Promise<NotFound<User> | DatabaseException<User> | UserDetails> {
    const found = await this.users.findById(userId); (4)
    const response = await permitted.mapData(async user => {
      return new UserDetails(user, false);
    });
    return response;
  }

}
1 The custom FP class UserDetails was defined in the FP documentation
2 https://docs.nestjs.com/openapi/introduction does not expose models defined in oneOf constructs, which is what oneOfFP uses, so OpenAPI must be explicitly told to document the models.
3 This example uses the UserService defined in documentation for Formulaic’s entity-service.
4 findById returns either EntityNotFound<User> or Data<User>, as defined by the entity-service - EntityNotFound is a sub-type of NotFound.

This controller will be revisited to add authentication checks and error responses with Formulaic’s auth-module.