Skip to content
This repository was archived by the owner on Nov 4, 2022. It is now read-only.
/ typescript-api Public archive

Skeleton project for easy extendable TypeScript APIs.

License

Notifications You must be signed in to change notification settings

pascaliske/typescript-api

Folders and files

NameName
Last commit message
Last commit date
Nov 3, 2022
Oct 26, 2021
May 3, 2021
Feb 1, 2019
Jun 19, 2018
Jun 24, 2019
Oct 26, 2021
Jun 19, 2018
Nov 3, 2022
Nov 3, 2022
Jun 19, 2018
Nov 3, 2022
Nov 3, 2022
Aug 3, 2020
May 13, 2020
Dec 16, 2018
Nov 3, 2022

Repository files navigation

TypeScript API Skeleton

GitHub Tag Build Status Awesome Badges

Setup

To install the skeleton use the following commands:

$ git clone https://github.com/pascaliske/typescript-api.git my-api
$ yarn install

Development

Start the server using this command:

$ yarn run start

For using the built in file watch you can also start the server using this command:

$ yarn run watch

To execute the tests run this command:

$ yarn run test

Controllers

You can write controllers the following way:

import { Service } from 'typedi'
import { JsonController, Get, Param } from 'routing-controllers'
import { Repository } from 'typeorm'
import { InjectRepository } from 'typeorm-typedi-extensions'
import { ApiResponse } from 'typings'
import { User } from './models/user'

/**
 * Creates the controller as an dependency injected service
 */
@Service()
@JsonController('/user')
export class UserController {
    /**
     * Model repositories
     */
    @InjectRepository(User) private userRepo: Repository<User>

    /**
     * Defines an endpoint for "GET /api/user"
     */
    @Get('/')
    public async readAll(): Promise<ApiResponse<User[]>> {
        return this.userRepo.find()
    }

    /**
     * Defines an endpoint for "GET /api/user/:id"
     */
    @Get('/:id')
    public async readOne(@Param('id') id: number): Promise<ApiResponse<User>> {
        return this.userRepo.findOne(id)
    }
}

Models

The corresponding model for the demo controller above:

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'

@Entity()
export class User {
    /***** columns *****/

    @PrimaryGeneratedColumn() public id: number

    @Column({
        unique: true,
        nullable: false,
    })
    public email: string

    @Column() public password: string

    /***** relations *****/
}

Tests

You can test you controllers the following way:

import test from 'ava'
import { factory } from '../../testing/setup'

test('GET /user', async t => {
    // required for supertest, count of asserts inside this test
    t.plan(2)

    // creates a server instance for access with supertest lib
    const server = await factory()
    const response = await server.get('/api/user')

    t.is(response.status, 200)
    t.is(response.body.status, 200)
})

Services

You can create custom services the following way:

import { Service } from 'typedi'

@Service({
    global: true,
})
export class CustomService {
    public foo(bar: string): string {
        return bar
    }
}

The service is then globally available as a singleton and can be injected into a controller:

import { Service, Inject } from 'typedi'
import { JsonController, Get } from 'routing-controllers'
import { ApiResponse } from 'typings'
import { CustomService } from '../../services/my-custom.service.ts'

@Service()
@JsonController('/user')
export class UserController {
    @Inject() private customService: CustomService

    @Get('/demo')
    public async demo(): Promise<ApiResponse<string>> {
        return this.customService.foo('DEMO!')
    }
}

License

MIT © Pascal Iske