@t2ee/vader

Koa Router in Typescript, Servlet-Like API

Introduction

@t2ee/vader is a routing component (with JAX-RS like grammars). It is to be used with [email protected].

Installation

npm i reflect-metadata @t2ee/core @t2ee/sl4js [email protected] @t2ee/vader -S

Usage

Basic Usage

import 'reflect-metadata';
import * as Koa from 'koa';
import {
    Path,
    Router,
    QueryParam,
    Response,
    GET,
} from '@t2ee/vader';

const router = Router.newInstance();

@Path('')
class Controller {

    @GET
    @Path('/say')
    say(@QueryParam('message') message: string) {
        const response = new Response();
        response.body = message;
        return response;
    }
}

router.use(Controller);
const app = new Koa();
app.use(router.routes());
app.listen(8080);

Receive POST Data

@Path('/')
class Controller {

    @POST
    @Consumes('application/json')
    @Path('/login')
    say(@Body body) {
        const response = new Response();
        response.body = body;
        return response;
    }
}

Use Middlewares

Middlewares can be either injected on classes or methods.

Direct Register Middlewares


async function handler(request: Request): Promise<Request> {
    if (request.headers.get('SECRET-KEY') !== 'secret') {
        throw new Error('WRONG!!!!!!');
    }
    return request;
}

@Before(handler)
class Controller {
}

Through Class Methods


async function handler(request: Request): Promise<Request> {
    if (request.headers.get('SECRET-KEY') !== 'secret') {
        throw new Error('WRONG!!!!!!');
    }
    return request;
}

@Before('checkSecret')
class Controller {
    async checkSecret(@Context request: Request): Promise<Request> {
        if (request.headers.get('SECRET-KEY') !== 'secret') {
            throw new Error('WRONG!!!!!!');
        }
        return request;
    }
}

Register For All Routes

router.userMiddlewares(before, afters, afterAlls);

Custom Context Variables

Binding directly

Let’s say we wanted to bind headers SECRET-KEY to a variable.


function Secret(target: Object, key: string) {
    return Contexted((req: Request) => req.headers.get('SECRET-KEY'));
}

class Controller {
    @Secret secret: string;
}

Binding by class

class User {
    username: string;
    password: string;
}

router.provideContext(User, (req: Request) => {
    const user = new User();
    // fill up user
    return user;
});

class Controller {
    @Context user: User;
}

Handlers

Exceptions and extra configurations are implemented by Auto Configuration. To provide a custom handler, see example below.

@Configuration
class Config {
    @Bean('NotFoundHandler)
    notFoundHandler(): NotFoundHandler {
        return {
            async handle(req: Request, data: void): Promise<core.Response> {
                // handle unmatched routes here.
            }
        }
    }

    @Bean('ErrorHandler')
    errorHandler(): ErrorHandler {
        return {
            async handle(req: Request, error: Error): Promise<core.Response> {
                // handle uncaught errors here.
            }
        }
    }
}

API

Coming soon …

Coming soon…