Getting started

Required environment

You need NodeJS 10+ to be installed

Working samples

  • Hello, world! - very simple client-server application that send request to server and return response
  • Chat demo - simple chat demo with events

How to prepare server for TypedAPI

# install typedapi libraries with websocket library
npm install --save typedapi-core typedapi-server typedapi-server-ws
# install typedapi parser for dev
npm install --save-dev typedapi-parser

Then you need to create Api object anywhere in server directory.
For "Hello, world!" application it will be looks like:

export class Api {
    async hello(name: string): Promise<string> {
        return `Hello, ${name}!`
    }
}

Api object can contain:

  • Methods that return Promises
  • Events objects
  • Child objects with same contents

How to prepare client

# install typedapi libraries with websocket support
npm install --save typedapi-core typedapi-client typedapi-client-browser-ws

Generate API reflections

TypedAPI need api reflections for validation purposes. When creating reflection, it will automatically generate reflections file for client and server. For client will be also generated API interface.

To run generator, you should call typedapi-parse from server directory. It will be in ./node_modules/.bin directory. typedapi-parse command receive parameters:

typedapi-parse [sourceFilename] [sourceObjectName] [outFilename] [reflectionOutFileName]

Where:

  • sourceFilename: Path to file where your Api object
  • sourceObjectName: Class name in file (ex Api, Backend, MyCompanyApi etc)
  • outFilename: Ouput file name for client where will be interface, reflection, and Api factory
  • reflectionOutFileName: Ouput file name for server where will be stored Api reflection

For example, you can run:

./node_modules/.bin/typedapi-parse Api.ts Api ../client/apiReflection.ts apiReflection.ts

You also can add command to package.json file:

{
    "scripts": {
        parseApi: "typedapi-parse Api.ts Api ../client/apiReflection.ts apiReflection.ts"
    }
}

And run it like:

npm run parseApi

How to run server

Example script how to run server:

import { WebSocketServer } from "typedapi-server-ws"
import { buildMap } from "typedapi-server"
// Reflection generated using typedapi-parse
import { reflection } from "./apiReflection"
// Your Api object
import { Api } from "./Api"

new WebSocketServer({
    apiMap: buildMap(reflection, new Api),
    port: 8090
})

How to connect client

Example script how to connect client to server:

// Import TypedAPI libraries
import { WebSocketTransport } from "typedapi-client-browser-ws"
// Reflection generated using typedapi-parse
import { createClient } from "./apiReflection"

const api = createClient({ transport })

// And then you can run your API Methods
let result = await api.hello(name)

Authorization

To implement users authorization in your project you should realize method that return AuthDataResponse
Interface AuthDataResponse:

export type AuthDataResponse = {
    newAuthData: {
        id?: string | number
        groups?: string[]
        name?: string
        email?: string
        phone?: string
    }
    // response value will be return to user,
    // newAuthData will be removed and used only for internal usage
    response: boolean
}

Example of Api that implement users` authorization.

import { AuthDataResponse } from "typedapi-server"

export class ClientApi {

    /**
     * This method check user`s name and password, and, if success, it return user`s id and groupd.
     * That data will be stored in user`s connection data and will be passwed to methods when need.
     **/
    async login(username: string, password: string): Promise<AuthDataResponse> {
        let user = await usersRepository.login(username, password)
        if(!user) {
            return {
                response: false,
                newAuthData: {}
            }
        } else {
            return {
                response: true,
                newAuthData: {
                    id: user.id,
                    groups: user.groups
                }
            }
        }
    }

    /**
     * Logout and return empty auth data
     **/
    async logout(): Promise<AuthDataResponse> {
        return {
            response: true,
            newAuthData: {}
        }
    }

    /**
     * ApiUserID will be atumatically injected by user`s auth data.
     * If user not authorized, he will receive NotAuthorizedError
     **/
    async getUserData(apiUserId: number): Promise<SomeUserData> {
        let userData = await usersRespotory.getUserData(apiUserId)
        return userData
    }
}


For more information see Docs