I made Express faster than Fastify (100x faster JSON)

Outline

Hello, I am developer of typia, and studying fastify in nowadays.

During the study, I could understand why fastify is faster than express, and proceeded. Also, I did an experiment imitating the secret of the fastify in express with…


This content originally appeared on DEV Community and was authored by Jeongho Nam

Outline

Hello, I am developer of typia, and studying fastify in nowadays.

During the study, I could understand why fastify is faster than express, and proceeded. Also, I did an experiment imitating the secret of the fastify in express with typia's faster JSON stringify function.

From the experiment (benchmark), I could get interesting result that express became faster than fastify. So I would like to share it with you.

JSON stringify benchmark in server level

Made express to be faster than fastify

What typia is

// RUNTIME VALIDATORS
export function is<T>(input: unknown | T): input is T; // returns boolean
export function assert<T>(input: unknown | T): T; // throws TypeGuardError
export function validate<T>(input: unknown | T): IValidation<T>; // detailed
export const customValidators: CustomValidatorMap; // can add custom validators

// STRICT VALIDATORS
export function equals<T>(input: unknown | T): input is T;
export function assertEquals<T>(input: unknown | T): T;
export function validateEquals<T>(input: unknown | T): IValidation<T>;

// JSON
export function application<T>(): IJsonApplication; // JSON schema
export function assertParse<T>(input: string): T; // type safe parser
export function assertStringify<T>(input: T): string; // safe and faster
    // +) isParse, validateParse 
    // +) stringify, isStringify, validateStringify

// MISC
export function random<T>(): Primitive<T>; // generate random data
export function clone<T>(input: T): Primitive<T>; // deep clone
export function prune<T extends object>(input: T): void; // erase extra props
    // +) isClone, assertClone, validateClone
    // +) isPrune, assertPrune, validatePrune

Before telling detailed stories, I'll introduce typia for a while.

It is a runtime validator library for TypeScript, which can perform above features just by only one line, just by utilizing pure TypeScript type. On the other hand, all of other alternative libraries require extra and duplicated schema definitions, which are different with the TypeScript type.

Furthermore, validation speed of typia is much faster than others. Comparing validation speed, typia is maximum 15,000x faster than class-validator. When it comes to the JSON stringify function, typia is maximum 100x faster than class-transformer and even type safe.

Secret of fastify

fastify is a competitive library of express, which uses faster speed as a weapon.

And one of the reason why fastify is faster than express is, fast-json-stringify. fast-json-stringify is another library what fastify team had developed, which boosts up JSON conversion speed by analyzing JSON schema definition.

By using the fast-json-stringify library, fastify can serialize JSON string much faster than express, and such difference makes fastify to be faster than express.

const fastJson = require('fast-json-stringify')

// REQUIRES JSON SCHEMA DEFINITION
const stringify = fastJson({
    title: 'Example Schema',
    type: 'object',
    properties: {
        firstName: {
            type: 'string'
        },
        lastName: {
            type: 'string'
        },
        age: {
            description: 'Age in years',
            type: 'integer'
        },
        reg: {
            type: 'string'
        }
    }
});

// MAKES JSON SERIALIZATION FASTER
console.log(stringify({
    firstName: 'Matteo',
    lastName: 'Collina',
    age: 32,
    reg: /"([^"]|\\")*"/
}));

Stringify Benchmark

fast-json-stringify is faster than native JSON.stringify() function

Imitate secret of fastify in express

import typia from "typia";

// PURE TYPESCRIPT TYPE
interface IPerson {
    firstName: string;
    lastName: string;
    age: number; // Age in years
    reg: RegExp;
}

// EASIER THAN ANY OTHER LIBRARIES
typia.stringify<IPerson>({
    firstName: 'Matteo',
    lastName: 'Collina',
    age: 32,
    reg: /"([^"]|\\")*"/
});

Studying source code of fastify, I could understand why fastify is faster. By the way, typia has the same function like fast-json-stringify. Therefore, imitating secret of fastify was easily possible, too.

//----
// EXPRESS + TYPIA
//----
import express from "express";
import typia from "typia";

const server: express.Express = express();
const reply =
    <T>(stringify: (input: T) => string | null) =>
    (data: T) =>
    (_req: express.Request, res: express.Response) =>
        res
            .status(200)
            .header("Content-Type", "application/json")
            .send(stringify(data));

// VERY EASY TO IMPLEMENT
server.get(
    "/ObjectSimple",
    reply(typia.createIsStringify<ObjectSimple[]>())
         (storage.ObjectSimple),
);

Here is the code imitating fastify library in express with typia.

I think that my solution is much easier than fastify, because typia does not require complicate JSON schema definition, and it just requires only pure TypeScript type.

Do you agree?

//----
// FASTIFY
//----
import fastify, { FastifyReply, FastifyRequest } from "fastify";
import typia from "typia";

const server = fastify();
const schema = (app: typia.IJsonApplication) => {
    const definitions: Record<string, typia.IJsonSchema> = {};
    for (const [key, value] of Object.entries(app.components.schemas))
        definitions[key.replace("#/definitions/", "")] = value;

    return {
        schema: {
            response: {
                200: {
                    ...app.schemas[0]!,
                    definitions,
                },
            },
        },
    };
};
const reply = (data: object) => (_i: FastifyRequest, o: FastifyReply) =>
    o.send(data);

// DEFINING JSON SCHEMA IS A TERRIBLE WORK
// THEREFORE, I JUST USED typia.application() FUNCTION
server.get(
    "/ObjectSimple",
    schema(typia.application<[ObjectSimple[]], "ajv", "#/definitions">()),
    reply(storage.ObjectSimple),
);

Also, to proceed experiment (benchmark) in the fastify side, I wrote server code of fastify, too. By the way, as defining JSON schema is a terrible work for me, I just generated the JSON schema data through typia.application() function.

Measuring benchmark of those servers through autocannon (another library what fastify team had built), I could get awesome result. express became faster than fastify in some cases, just by utilizing typia.stringify() function.

JSON stringify benchmark on server

express became faster than fastify in some cases

Boost up your NestJS server speed

Validation Benchmark

class-validator and class-transformer are extremely slow

You know what? NestJS is utilizing class-validator and class-transformer. Do you remember? those libraries were slowest than any other libraries in the above benchmarks.

  • class-validators is 15,000x times slower than typia
  • class-transformer is 100x times slower than typia

If you replace them to nestia (wrappers of typia for NestJS) supported decorators, you can boost up your NestJS developed backend server speed. Just by replacing some decorator functions like below, your server program would be much faster.

import { Controller } from "@nestjs/common";
import { TypedBody, TypedRoute } from "@nestia/core";

import type { IBbsArticle } from "@bbs-api/structures/IBbsArticle";

@Controller("bbs/articles")
export class BbsArticlesController {
    /** 
     * Store a new content.
     * 
     * @param inupt Content to store
     * @returns Newly archived article
     */
    @TypedRoute.Post() // 100x faster and safer JSON.stringify()
    public async store(
        // 15,000x faster validator
        @TypedBody() input: IBbsArticle.IStore 
    ): Promise<IBbsArticle>; 
        // do not need DTO class definition, 
        // just fine with interface
}

Also, with the nestia, you can build evolved swagger than swagger. Furthermore, you can build SDK library (like tRPC), therefore, client deevelopers can use your API much easily and safely like below.

SDK utilization code

Frontend developers would be happy

fastify is still fast

Looking back above benchmark result, fastify is faster than combination of express and typia, when response data is small. If making the reponse data much smaller, fastify becomes always faster than express + typia.

I just assume that fastify has special optimized logic for header parsing, and reducing waiting time for each API call, but I don't know the exactly reason why. I need to study fastify more, and also need to study express, too.

I will fastify continuously, and will come back again with the reason why.

Thanks for reading my article, and hope my article was enjoyable.

Links


This content originally appeared on DEV Community and was authored by Jeongho Nam


Print Share Comment Cite Upload Translate Updates
APA

Jeongho Nam | Sciencx (2023-04-03T13:09:55+00:00) I made Express faster than Fastify (100x faster JSON). Retrieved from https://www.scien.cx/2023/04/03/i-made-express-faster-than-fastify-100x-faster-json/

MLA
" » I made Express faster than Fastify (100x faster JSON)." Jeongho Nam | Sciencx - Monday April 3, 2023, https://www.scien.cx/2023/04/03/i-made-express-faster-than-fastify-100x-faster-json/
HARVARD
Jeongho Nam | Sciencx Monday April 3, 2023 » I made Express faster than Fastify (100x faster JSON)., viewed ,<https://www.scien.cx/2023/04/03/i-made-express-faster-than-fastify-100x-faster-json/>
VANCOUVER
Jeongho Nam | Sciencx - » I made Express faster than Fastify (100x faster JSON). [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/04/03/i-made-express-faster-than-fastify-100x-faster-json/
CHICAGO
" » I made Express faster than Fastify (100x faster JSON)." Jeongho Nam | Sciencx - Accessed . https://www.scien.cx/2023/04/03/i-made-express-faster-than-fastify-100x-faster-json/
IEEE
" » I made Express faster than Fastify (100x faster JSON)." Jeongho Nam | Sciencx [Online]. Available: https://www.scien.cx/2023/04/03/i-made-express-faster-than-fastify-100x-faster-json/. [Accessed: ]
rf:citation
» I made Express faster than Fastify (100x faster JSON) | Jeongho Nam | Sciencx | https://www.scien.cx/2023/04/03/i-made-express-faster-than-fastify-100x-faster-json/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.