• +91 9790 650 659
  • This email address is being protected from spambots. You need JavaScript enabled to view it.

User Rating: 4 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Inactive

Setting Up Project

Make sure that you have NodeJS and MongoDB installed on your machine. After that, you have to install TypeScript Node.

npm install -g typescript ts-node

In order to test HTTP request, we can use Postman to send sample requests.

Step 1: Initiate a Node project

Create a project folder and initiate the npm project. Remember to answer all the question, and you can edit it any time after that

mkdir restful-webapi-with-node
cd restful-webapi-with-node
npm init

Step 2: Install all the dependencies

npm install --save @types/express express body-parser mongoose nodemon

Step 3: Configure the TypeScript configuration file

The idea is to put all the TypeScript files in the root folder with sub folders for development purpose, then for the production, we will save all the Javascript files in the dist folder. And of course, we will take advantage of the ES2015 in the project.

// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"pretty": true,
"sourceMap": true,
"target": "es6",
"outDir": "./dist",
"baseUrl": "./"
},
"exclude": [
"node_modules"
]
}

So whenever we run the tsc command, all the ts files in the lib folder will be compiled to js files in the dist folder

tsc

Step 4: edit the running scripts in package.json

"scripts": {
"build": "tsc",
"dev": "ts-node ./server.ts",
"start": "nodemon ./dist/server.js",
"prod": "npm run build && npm run start"
}

So, for the development, we can run a test server by running

npm run dev

For production

npm run prod

Step 5: getting started with the base configuration

You will need sooner or later the package body-parse for parsing incoming request data.

// ./app.ts
import * as express from "express";
import * as bodyParser from "body-parser";

class App {

public app: express.Application;

constructor() {
this.app = express();
this.config();
}

private config(): void{
// support application/json type post data
this.app.use(bodyParser.json());

//support application/x-www-form-urlencoded post data
this.app.use(bodyParser.urlencoded({ extended: false }));
}
}

export default new App().app;

Create ./server.ts file

// ./server.ts
import app from "./app";
const PORT = 3000;

app.listen(PORT, () => {
console.log('Express server listening on port ' + PORT);
})

From now, although you can not send a HTTP request yet, you still can test the project by running npm run dev.

Implement routing and CRUD

Step 1: Create TS file for routing

Remember in part 1 of this project. We save everything in the root folder for microservices. So I will create routes folder with a file named userRoutes.ts that will save all the routes for this project.

// ./routes/userRoutes.ts
import {Request, Response} from "express";

export class Routes {
public routes(app): void {
app.route('/')
.get((req: Request, res: Response) => {
res.status(200).send({
message: 'GET request successfulll!!'
})
})
}
}

After creating our first route, we need to import it to the ./app.ts.

// ./app.ts
import * as express from "express";
import * as bodyParser from "body-parser";
import { UserRoutes } from "./routes/userRoutes";

class App {

public app: express.Application;
public userRoutes: UserRoutes = new Routes();

constructor() {
this.app = express();
this.config();
this.userRoutes.routes(this.app);
}

private config(): void{
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({ extended: false }));
}
}

Now, you can send GET request to your application (http://localhost:3000) directly or by using Postman.

Step 2: Building CRUD for the Web APIs

I assume that you have a basic understanding of HTTP request (GET, POST, PUT and DELETE). If you don’t, it is very simple:

  • GET: for retrieving data
  • POST: for creating new data
  • PUT: for updating data
  • DELETE: for deleting data

Now we will build the routing for building a user CRM that saves, retrieves, updates and deletes user info.

// ./routes/userRoutes.ts
import {Request, Response} from "express";

export class Routes {

public routes(app): void {

app.route('/')
.get((req: Request, res: Response) => {
res.status(200).send({
message: 'GET request successfulll!!!!'
})
})

// User
app.route('/user')
// GET endpoint
.get((req: Request, res: Response) => {
// Get all users
res.status(200).send({
message: 'GET request successfulll!!'
})
})
// POST endpoint
.post((req: Request, res: Response) => {
// Create new user
res.status(200).send({
message: 'POST request successfulll!!'
})
})

// User detail
app.route('/user/:userId')
// get specific user
.get((req: Request, res: Response) => {
// Get a user information
res.status(200).send({
message: 'GET request successfulll!!'
})
})
.put((req: Request, res: Response) => {
// Update a user
res.status(200).send({
message: 'PUT request successfulll!!'
})
})
.delete((req: Request, res: Response) => {
// Delete a user
res.status(200).send({
message: 'DELETE request successfulll!!'
})
})
}
}

Now the routes are ready for getting HTTP request.

Using Controller and Model for Web APIs

Step 1: Create Model for your data

All the model files will be saved in ./models folder. We will define the structure of the User by using Schema from Mongoose.

//   ./models/userModel.ts
import * as mongoose from 'mongoose';

const Schema = mongoose.Schema;

export const UserSchema = new Schema({
firstName: {
type: String,
required: 'Enter a first name',
},
lastName: {
type: String,
required: 'Enter a last name',
},
email: {
type: String,
},
company: {
type: String,
},
phone: {
type: Number
},
created_date: {
type: Date,
default: Date.now,
},
});

This model will be used inside the controller where we will create the data.

Step 2: Create your first Controller

Remember we have created CRUD place holder for communicating with the server. Now we will apply the real logic to the route and controller.

  1. Create a new user (GET request)

All the logic will be saved in the ./controllers/userController.ts

//   ./controllers/userController.ts
import * as mongoose from 'mongoose';
import { UserSchema } from './models/userModel';
import { Request, Response } from 'express';

const User= mongoose.model('User', UserSchema);
export class UserController{
...
public addNewUser (req: Request, res: Response) {                
const user= new User(req.body);

user.save((err, user) => {
if(err){
res.send(err);
}
res.json(user);
});
}

In the route, we don’t have to pass anything.


// ./routes/userRoutes.ts
import { UserController } from "./controllers/userController";
public userController: UserController = new UserController();
// Create a new user
app.route('/user')
.post(this.userController.addNewUser);

2. Get all users (GET request)

All the logic will be saved in the ./controllers/userController.ts

//   ./controllers/userController.ts
...
public getUsers (req: Request, res: Response) {           
User.find({}, (err, users) => {
if(err){
res.send(err);
}
res.json(users);
});
}
}

After that, we will import UserController and apply getUsers method.

// ./routes/userRoutes.ts
// Get all Users
app.route('/users')
.get(this.userController.getUsers)

3. View a single user (GET method)

We need the ID of the user in order to view the user info.

//   ./controllers/userController.ts
public getUser (req: Request, res: Response) {           
User.findById(req.params.userId, (err, user) => {
if(err){
res.send(err);
}
res.json(user);
});
}

In the routes, we simply pass the ‘/user/:userId’

// ./routes/userRoutes.ts
// get a specific user
app.route('/user/:userId')
.get(this.userController.getUserWithID)

4. Update a single user (PUT method)

Remember that, without {new: true}, the updated document will not be returned.

//   ./controllers/userController.ts
public updateUser (req: Request, res: Response) {           
User.findOneAndUpdate({ _id: req.params.userId }, req.body, { new: true }, (err, user) => {
if(err){
res.send(err);
}
res.json(user);
});
}

In the routes,

// ./routes/userRoutes.ts
// update a specific user
app.route('/user/:userId')
.put(this.userController.updateUser)

5. Delete a single user (DELETE method)

//   ./controllers/userController.ts
public deleteUser (req: Request, res: Response) {           
User.remove({ _id: req.params.userId }, (err, user) => {
if(err){
res.send(err);
}
res.json({ message: 'Successfully deleted user!'});
});
}

In the routes,

// ./routes/userRoutes.ts
// delete a specific user
app.route('/user/:userId')
.delete(this.userController.deleteUser)

* Remember that you don’t have to call app.route(‘/user/:userId’) every single time for GET, PUT or DELETE a single user. You can combine them

// ./routes/userRoutes.ts
app.route('/user/:userId')
// edit specific user
.get(this.userController.getUser)
.put(this.userController.updateUser)
.delete(this.userController.deleteUser)

From now, your model and controller are ready. 

You can enjoy referring the code which is written by me for Restful Web API's with Node, Express, Typescript and MongoDB.

Github URL: https://github.com/ranjithprabhuk/Restful-web-api-with-node-express-mongo-and-typescript

Thanks for reading.


Search

Subscribe

Google Adsense