All Projects → ollita7 → kiwi

ollita7 / kiwi

Licence: other
Built using only nodejs core. Lightweight, intuitive together with great performance and response timing.

Programming Languages

typescript
32286 projects
HTML
75241 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to kiwi

Type Graphql
Create GraphQL schema and resolvers with TypeScript, using classes and decorators!
Stars: ✭ 6,864 (+15153.33%)
Mutual labels:  controllers, decorators
tsioc
AOP, Ioc container, Boot framework, unit testing framework , activities workflow framework.
Stars: ✭ 15 (-66.67%)
Mutual labels:  decorators
vue3-oop
使用类和依赖注入写vue组件
Stars: ✭ 90 (+100%)
Mutual labels:  decorators
hapi-decorators
Decorators for HapiJS routes
Stars: ✭ 65 (+44.44%)
Mutual labels:  decorators
tinsel
Use Decorators to Transform Functions
Stars: ✭ 18 (-60%)
Mutual labels:  decorators
common-injector
Heavily influenced by Angular and it's dependency injection. Inspired by Angular and Indiv.
Stars: ✭ 18 (-60%)
Mutual labels:  decorators
stupid-python-tricks
Stupid Python tricks.
Stars: ✭ 112 (+148.89%)
Mutual labels:  decorators
toxic-decorators
Library of Javascript decorators
Stars: ✭ 26 (-42.22%)
Mutual labels:  decorators
reducer-class
Boilerplate free class-based reducer creator. Built with TypeScript. Works with Redux and NGRX. Has integration with immer.
Stars: ✭ 25 (-44.44%)
Mutual labels:  decorators
capsid
💊 Declarative DOM programming library. Lightweight (1.79 kb).
Stars: ✭ 76 (+68.89%)
Mutual labels:  decorators
next-api-decorators
Collection of decorators to create typed Next.js API routes, with easy request validation and transformation.
Stars: ✭ 187 (+315.56%)
Mutual labels:  decorators
easy cache
Caching and invalidation have never been so easy
Stars: ✭ 28 (-37.78%)
Mutual labels:  decorators
eslint-plugin-decorator-position
ESLint plugin for enforcing decorator position
Stars: ✭ 32 (-28.89%)
Mutual labels:  decorators
graphql-ts
Graphql implementation in Typescript using decorator
Stars: ✭ 63 (+40%)
Mutual labels:  decorators
discord.ts
🤖 Create your discord bot by using TypeScript and decorators!
Stars: ✭ 315 (+600%)
Mutual labels:  decorators
cognises-flask
Flask Cognises: AWS Cognito group based authorization with user management
Stars: ✭ 16 (-64.44%)
Mutual labels:  decorators
organiser
An organic web framework for organized web servers.
Stars: ✭ 58 (+28.89%)
Mutual labels:  decorators
legacy-decorators-migration-utility
🔝 A command line utility to upgrade your JavaScript files from the legacy decorators proposal to the new one.
Stars: ✭ 20 (-55.56%)
Mutual labels:  decorators
route-decorators
ES7 decorators that simplify Koa and Express route creation
Stars: ✭ 71 (+57.78%)
Mutual labels:  decorators
polog
Логирование должно быть красивым
Stars: ✭ 26 (-42.22%)
Mutual labels:  decorators

logo

Framework to help building a REST API using typescript and node.

Build Status Coverage Status

Table of Contents

Installation

  1. Install module: npm install kiwi-server --save

    npm install kiwi-server-cli -g

    Optional: https://github.com/ollita7/kiwi-cli

  2. Add these options to the tsconfig.json file of your project:

    {
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true
    }

Sample

  1. Create your first controller class user-controller.ts

    import { Get, Post, Put, JsonController, Param, Body, QueryParam, Authorize, HeaderParam, Delete } from '../../../src/index';
    import { UserModel } from '../../models/models';
    import { isNil } from 'lodash';
    import { Utils } from '../../utils';
    
    @JsonController('/user')
    export class UserController {
        constructor() {}
    
        @Authorize(['Admin'])
        @Post('/create')
        public create(@Body() user: UserModel) {
            user.id = Utils.userList.length + 1;
            Utils.userList.push(user);
            return user;
        }
    
        @Authorize(['Admin'])
        @Get('/get/:id')
        public getById(@Param('id') id: number) {
            var user = Utils.userList.filter(function(obj) {
            return obj.id === id;
            });
    
            return user;
        }
    
        @Authorize(['Admin'])
        @Put('/update')
        public update(@Body() user: UserModel) {
            let userAux = Utils.userList.find(x => x.id == user.id);
            let index = Utils.userList.indexOf(userAux);
            Utils.userList[index] = user;
            return true;
        }
    
        @Authorize(['Admin'])
        @Delete('/delete/:id')
        public delete(@Param('id') id: number) {
            Utils.userList = Utils.userList.filter(function(obj) {
            return obj.id !== id;
            });
            return true;
        }
    }

    We can use QueryParams to get an object with the keys and values that we send on the url.

    For example if you send something like http://.../testcontroller/queryparam/1?name=guille&lastname=fernandez you will receive an object like below:

        @Get('/listFilter')
        public listFilter(@QueryParam() params: any) {
            if (!isNil(params)) {
            var users = Utils.userList.filter(function(obj) {
                return obj.name === params.name && obj.age === +params.age;
            });
            }
            return users;
        }
    {
        "name": "guille",
        "age": 33
    }

    We can use HeaderParams to get http headers. In the next example we are going to receive the token HTTP header if it exists.

    @Get('/search/:name')
    public queryparam(@Param('name') name: string, @HeaderParam('token') token: string) {
        this.aux.print(token);
        if (!isNil(name)) {
        var users = Utils.userList.filter(function(obj) {
            return obj.name === name;
        });
        }
        return users;
    }
  2. After creating the controller, create the server that uses that controller.

    import { createKiwiServer } from 'kiwi-server';
    import { UserController } from './controllers/user/user-controller';
    
    const options = {
        controllers: [UserController],
    };
    const server = createKiwiServer(options);
    server.listen(8086);

Middlewares

  1. You can create middlewares to execute activities before and after the execution of an action.

    For example to enable CORS we use a specific middleware that is in charge of adding the HTTP headers for that. It's important to execute next if you want the flow to continue executing. Otherwise the flow finishes and you must do something with the response, if you don't the client never gets a response. Below is an example that executes before any action.

    Also you can add the order that you want to execute your middlewares:

    import { IMiddleware } from '../../src/middlewares/middleware';
    import { MiddlewareAfter } from '../../src/decorators/middlewareAfter';
    import * as http from 'http';
    
    @MiddlewareAfter(1)
    export class UserMiddleware implements IMiddleware{
    
        execute(request: http.IncomingMessage, response: http.ServerResponse, next: any){
            response.setHeader( 'Authorization', 'token' );
            console.log('UserMiddleware execute');
            next();
        }
    }

Authorization

  1. On the controller specify what actions need to be authorized, using the @Authorize decorator. In the following example we only need to authorize the put action. You can also put the decorator in the controller if all the actions need to be authorized.

    @Get('/list')
    public listAll() {
        return Utils.userList;
    }
    
    @Authorize(['Admin'])
    @Put('/update')
    public update(@Body() user: UserModel) {
        let userAux = Utils.userList.find(x => x.id == user.id);
        let index = Utils.userList.indexOf(userAux);
        Utils.userList[index] = user;
        return true;
    }
  2. On the server define the function that is going to be executed everytime an action or a controller has the @Authorize decorator. If that function returns false the service is going to return 401 HTTP error, in other case it will continue the normal execution path.

    import { createKiwiServer } from 'kiwi-server';
    import { UserController } from './controllers/user/user-controller';
    
    async function validateAuthentication(request: http.IncomingMessage, roles: Array<string>): Promise<AuthorizeResponse | boolean> {
        console.log(roles);
        return new AuthorizeResponse(403, 'custom message');
        // return true if want to continue execution
    }
    
    const options = {
        controllers: [UserController],
        authorization: validateAuthentication
    }
    const server = createKiwiServer(options);
    server.listen(8086);

CORS

  1. You can enable cross domain by configuration

    import { createKiwiServer } from 'kiwi-server';
    import { UserController } from './controllers/user/user-controller';
    
    const options = {
        controllers: [UserController],
        cors: {
            enabled: true,
            domains: ['domain1.com', 'domain2.com']
        }
    }
    const server = createKiwiServer(options);
    server.listen(8086);

Prefix

  1. You can add a prefix for all the URLs. In the following example, all the URLs will have the v1/ prefix:

    import { createKiwiServer } from 'kiwi-server';
    import { UserController } from './controllers/user/user-controller';
    
    const options = {
        controllers: [UserController],
        prefix: 'v1/'
    }
    const server = createKiwiServer(options);
    server.listen(8086);

Dependency Injection

  1. You can use dependency injection in your controllers, by adding arguments to the constructor. Then you can use that in any method that you want.

    import { Get, Post, Put, JsonController, Param, Body, QueryParam, Authorize, HeaderParam, Delete } from '../../../src/index';
    import { UserModel } from '../../models/models';
    import { isNil } from 'lodash';
    import { AuxiliaryFunctions } from '../../auxiliaryFunctions';
    
    @JsonController('/user')
    export class UserController {
        constructor(private aux: AuxiliaryFunctions) {}
    
        @Get('/search/:name')
        public queryparam(@Param('name') name: string, @HeaderParam('token') token: string) {
            this.aux.print(token);
            if (!isNil(name)) {
            var users = Utils.userList.filter(function(obj) {
                return obj.name === name;
            });
            }
            return users;
        }
    }

Sockets

  1. socket.io is integrated to our framework. Enable socket support by adding the socket property to the options.

    const options = {
        controllers: [UserController],
        documentation: {
            enabled: true,
            path: '/apidoc'
        },
        socket: true
    }
    
    const server = createKiwiServer(options, socketInit);
    
    function socketInit() {
        const io = getSocket();
        io.on('connection', (socket: any) => {
            socket.userId  = socket.handshake.query.user;
        });
    }

    Finally use getSocket in any place of the application and start using it.

Documentation

  1. Enable automatic swagger documentation, setting the path where it will be accessible.

    import { createKiwiServer } from 'kiwi-server';
    import { UserController } from '../controllers/user/user-controller';
    
    const options = {
        controllers: [UserController],
        prefix: 'v1/',
        cors: true,
        documentation: {
            enabled: true,
            path: '/apidoc'
        }
    }
    const server = createKiwiServer(options);
    server.listen(8086);
  2. Decorate your models

    import { IsString, IsNumber, IsArray } from '../../src/index'
    
    export class AddressModel {
        @IsString() public street: string;
        @IsNumber() public number: number;
    }
    
    export class UserModel {
        @IsNumber() public id: number;
        @IsString()  public name: string;
        @IsString()  public lastname: string;
        @IsNumber() public age: number;
        @IsArray(() => AddressModel) public address: AddressModel[];
    }
  3. Visit the documentation page, in this example it would be at http://localhost:8086/v1/apidoc

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].