Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TypeStack] Make FoalTS more "DRY": serialization, validation & OpenAPI generation #460

Closed
LoicPoullain opened this issue Jun 14, 2019 · 1 comment

Comments

@LoicPoullain
Copy link
Member

Issue

Writing a simple REST API can be quite repetitive in Foal because we may have to write the same thing three times: the entity, the validation schema (AJV) and the OpenAPI request body.

The version 1 of Foal (June Release) will include a new feature to directly generate the OpenAPI request body from the validation schema thus reducing the code redundancy. #454

But this requires the developer to still define both the entity and validation schema.

Some libraries already exist to take care of this (including the serialization) and we could have an easy way to integrate them with Foal: class-validator, class-transformer, class-validator-jsonschema.

Related issue: #276

Constraints

  • FoalTS should still support the current way of building an API (with @ValidateBody, etc).
  • At any time, developers should be able to regain control on these hooks if necessary (especially when the API becomes more complex).

Possible solution

Add these hooks:

@ValidateBodyFromClass(c: Class)

@ApiRequestBodyFromClass(c: Class)

@SerializeBodyFromClass(c: Class)

@SerializeAndValidateBodyFromClass(c: Class)

Usage

// social-post.entity.ts
import { Contains, IsEmail, IsFQDN, IsInt, Length, Max, Min } from 'class-validator';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class SocialPost {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    @Length(10, 20)
    title: string;

    @Column()
    @Contains('hello')
    text: string;

    @Column()
    @IsInt()
    @Min(0)
    @Max(10)
    rating: number;

    @Column()
    @IsEmail()
    email: string;

    @Column()
    @IsFQDN()
    site: string;

}
// social-post.controller.ts
import { Context, Post, HttpResponseCreated } from '@foal/core';
import { SocialPost } from '../entities';
import { ApiRequestBodyFromClass, ValidateBodyFromEntity } from 'somewhre';

export class SocialPostController {

  @Post('/')
  @ValidateBodyFromEntity(SocialPost)
  @ApiRequestBodyFromClass(SocialPost)
  createSocialPost(ctx: Context) {
    return new HttpResponseCreated();
  }

  // OR

  @Post('/')
  @ValidateBodyFromEntity(SocialPost, { /* options */ })
  @ApiRequestBodyFromClass(SocialPost, { /* options */ })
  createSocialPost(ctx: Context) {
    return new HttpResponseCreated();
  }
}
@LoicPoullain LoicPoullain added this to Backlog in Issue tracking via automation Jun 14, 2019
@LoicPoullain LoicPoullain mentioned this issue Aug 13, 2019
8 tasks
@LoicPoullain LoicPoullain moved this from Backlog to To Do in Issue tracking Aug 19, 2019
@LoicPoullain LoicPoullain moved this from To Do to Work In Progress in Issue tracking Sep 12, 2019
@LoicPoullain LoicPoullain mentioned this issue Sep 12, 2019
5 tasks
@LoicPoullain
Copy link
Member Author

Package added in v1.2.0

Issue tracking automation moved this from Work In Progress to Done / Closed This Release Sep 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Issue tracking
  
Done / Closed This Release
Development

No branches or pull requests

1 participant