yonathan06 / fastify-now

File based routing for fastify https://github.com/fastify/fastify
MIT License
72 stars 8 forks source link

Automatically generate schema from types or types from schema? #29

Closed m1212e closed 1 year ago

m1212e commented 1 year ago

Hi,

is there any way to auto generate typescript types from a schema or the other way around? Writing it out twice seems like an unnessecary amount of boilerplate.

E.g.

import { NowRequestHandler } from "fastify-now";

export const POST: NowRequestHandler<{
  Body: { username: string; password: string };
}> = async (req, rep) => {
  console.log(req.body.username, req.body.password);
};

POST.opts = {
  schema: {
    body: {
      type: "object",
      properties: {
        username: {
          type: "string",
        },
        password: {
          type: "string",
        },
      },
    },
  },
};

Could become

import { NowRequestHandler } from "fastify-now";

const opts = {
  schema: {
    body: {
      type: "object",
      properties: {
        username: {
          type: "string",
        },
        password: {
          type: "string",
        },
      },
    },
  },
};

export const POST: NowRequestHandler<typeof opts> = async (req, rep) => {
  console.log(req.body.username, req.body.password); // still strongly typed as strings
};
POST.opts = opts;

I'm not sure if there is a way to do this. I know that zod has a functionality for converting schemas into typescript types.

Is typebox maybe able to do this?

m1212e commented 1 year ago

Ok, found a way to minimize the required Boilerplate:

import { NowRequestHandler } from "fastify-now";
import { Static, Type } from "@sinclair/typebox";

const User = Type.Object({
  password: Type.String(),
  email: Type.String({ format: "email" }),
});
export type UserType = Static<typeof User>;

export const POST: NowRequestHandler<{
  Body: UserType;
}> = async (req, rep) => {
  return "cool, it works";
};

POST.opts = {
  schema: {
    body: User,
  },
};

The docs have a good explaination on how to achieve this: https://www.fastify.io/docs/latest/Reference/TypeScript/#json-schema

m1212e commented 1 year ago

@yonathan06 Would it be ok if I create a pull request to add a hint for this pattern to the README? I think this could save future users a bit of time in research!

Also, maybe a generic helper function which recieves a callback and automatically adds the opts to the returned NowRequestHandler would be neat, so people don't accidentially forget to set the schema

yonathan06 commented 1 year ago

I'm not sure if it is related to this lib, as schema types are handled by fastify But feel free to suggest an edit to the README if you believe it will help others