TU Tran

Technologies should serve for business purpose.

NAVIGATION - SEARCH

Webapi and node

this article help you have a look how to implement RESTful in node in simple way.

there are some libraries do this already, I did not intend to replace that, just make some crazy code,  hope this can help us in future if we need some tricks to solve our problem.

Checkout the code from github at https://github.com/techcoaching/node_controller

Open this in visual code, we can see:

Just a few files, let me explain a little:

  • common folder:  this is where the common code, feature will be located.
  • main.ts: this is startup file.
  • controllers folder: this is where the controller of your app like in .net webapi project. there are 2 sample controllers, you can look at them for more understand if need.
  • in main.ts, there is special trick, just new an application type of nore (using express), register routes and start, so simple right:
let option:ICreateApplicationArg=<ICreateApplicationArg>{
    type:ApplicationType.NODE_EXPRESS
};

let routeConfigs:Hashtable<IRouteConfig>=BaseController.getRouteConfigs(CONTROLLERS);
let app:IApplication=ApplicationFactory.create(option);
app.configRoutes(routeConfigs);
app.start();

Run "npm install", this will download necessary packages from npm.

Run "npm run start", this will start the code and listen request at 3001 port. you can change this in common\application\nodeApplication.ts, you can improve the app to load these settings from external file. this was out of scope of this article:

let use any rest client and send some request to http://localhost:3001 as below, just want to make sure that we have the right setup:

Say hello:

Call with parameter:

Post data:

Please look at the testCotroller and usercontroller for more information.

ok, we can start the code, and make some noise with the api call. let continue creating new controller.

let start with sample:

let see the use-case:

I want to have the api which allow me to beable:

  • get the list of available accounts
  • update account information
  • get account info
  • delete account
  • add new account.account info include:
    • account Id, guid value
    • account name
    • status: value can be: normal, deleted

Let analyze:

  • Get the list of accounts, we need:
    • GET request
    • uri:<base uri>/accounts
    • return: array of accounts in json.
  • Update account info:
    • POST request, we use POST for both  create and update.
    • uri:<base uri>/accounts/<account id>
    • body: account in json format.
    • return: none
  • Get account info:
    • GET request
    • uri: <base uri>/accounts/<account id>
    • return: account info
  • Delete account:
    • DELETE request
    • uri: <base uri>/accounts/<account id>
    • return: account was deleted.
  • Add new account:
    • POST request
    • uri: <base uri>/accounts
    • body: account information in json format

Let implement:

 Step 1: add new controller for account (named AccountController):

import { UriPrefix } from "../common";
import { BaseController } from "../common/models/baseController";
@UriPrefix("/api/accounts")
export class AccountController extends BaseController{

}

and register this controller with the list of controllers:

import { TestController } from "./testController";
import { UserController } from "./userController";
import {AccountController} from "./Account/accountController";
export const CONTROLLERS:Array<any>=[
    TestController,
    UserController,
    AccountController
];

Step 2: get the list of available accounts:

Add new AccountController.ts:

import { Route, UriPrefix } from "../../common";
import guidHelper from "../../common/helpers/guidHelper";
import { BaseController } from "../../common/models/baseController";
import {Account} from "./account";
import {AccountService} from "./accountService";
@UriPrefix("/api/accounts")
export class AccountController extends BaseController{
    constructor(){
        super()
        if(!AccountService.accounts || AccountService.accounts.length==0){
            AccountService.accounts=[
                <Account>{id:guidHelper.create(), name:"Account 1", status: "normal"},
                <Account>{id:guidHelper.create(), name:"Account 2", status: "deleted"},
            ];
        }
    }
    @Route("")
    public getAccounts():Array<Account>{
        return AccountService.accounts;
    }
}

At line 5 and 7, this create the final uri mapped to getAccounts is "/ap/accounts". Just simple return the list of in-memory list.

and Account model:

export class Account{
    public id:string;
    public name:string;
    public status:string;
}

and AccountService:

import { Account } from "./account";

export class AccountService{
    public static accounts:Array<Account>=[];
}

It was rather simple at the moment, and the folder structure we have:

Just add new folder named "account" and move all the code for account into this folder.

Let run the code again, send request to "/api/accounts", we have the list with 2 accounts at the moment:

for now, we complete the first task is "get the list of available accounts", see the code in "feature/get_accounts" for more information of this.

Step 3: update account

it was mostly the same with "get accounts" task. add new method which handles update request:

 @Route(":id")
    @HttpPost()
    public updateAccount(id:string, name:string, status:string):string{
        let result:string=AccountService.updateAccount(id, name, status);
        return result;
    }

There are some notes:

  • At line 1, we register route which receive id as parameter.
  • At line 2, this handle post request for above uri.
  • At line 3, parameters will be injected automatically for us. name and status from the body of request.

Please do not pay attention on logic of method body. it was out of scope.

For the rest of code, you can checkout from "feature/update_account" branch.

Let update an account:

get the list of accounts, appropriated account was updated:

Step 4: Get an account:

add getAccount method which handle get request:

@Route(":id")
    @HttpGet()
    public getAccount(id:string):any{
        return AccountService.getAccount(id);
    }

 

 

For add new and delete account. Please continue do by your own with some hints:

  • Add new HttpDelete for handling delete account, simlar with HttpPost.
  • can use HttpPost for adding new account

 

 

Thank for reading.

Note: Please like and share to your friends if you think this is usefull article, I really appreciate

 

 

Add comment