Building RESTful Web APIs with Node.js, Express, MongoDB and TypeScript — Part 1
https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-1-2-195bdaf129cf
Building RESTful Web APIs with Node.js, Express, MongoDB and TypeScript — Part 2
https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-2-98c34e3513a2
Building RESTful Web APIs with Node.js, Express, MongoDB and TypeScript — Part 3
https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-3-d545b243541e
Building RESTful Web APIs with Node.js, Express, MongoDB and TypeScript — Part 4
https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-4-954c8c059cd4
Building RESTful Web APIs with Node.js, Express, MongoDB and TypeScript — Part 5
https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-5-a80e5a7f03db
https://github.com/dalenguyen/rest-api-node-typescript
Building RESTful Web APIs with Node.js, Express, MongoDB and TypeScript — Part 1
There is a course about how to build a Web APIs on Lynda, but they didn’t use TypeScript. So I decided to make one with TypeScript. There are lots of things that need to improve in this project. If you find one, please leave a comment. I’m appreciated that ;)
Part 2: Implement routing and CRUD
Part 3: Using Controller and Model for Web APIs
Part 4: Connect Web APIs to MongoDB or others
Part 5: Security for our Web APIs
Bonus: Building a “Serverless” RESTful API with Cloud Functions, Firestore and Express
Bonus: Handling Long Running API Requests in Nodejs
Before we get started
Make sure that you have NodeJS installed on your machine. After that, you have to install TypeScript and TypeScript Node.
npm install -g typescript ts-node
In order to test HTTP request, we can use Postman to send sample requests.
MongoDB preparation
You should install MongoDB on your local machine, or use other services such as mLab or Compose
If you installed MongoDB locally, you should install either Robo Mongo or Mongo Compass for GUI interface.
<canvas class="progressiveMedia-canvas js-progressiveMedia-canvas" width="75" height="55" style="display: block; vertical-align: baseline; position: absolute; top: 0px; left: 0px; width: 700px; height: 530.594px; margin: auto; box-sizing: border-box; visibility: hidden; opacity: 0; backface-visibility: hidden; transition: visibility 0s linear 0.5s, opacity 0.1s ease 0.4s;"></canvas>
[图片上传失败...(image-3f4e4a-1551512821339)]
<figcaption class="imageCaption" style="display: block; position: relative; left: 0px; width: 700px; top: 0px; margin-top: 10px; color: rgba(0, 0, 0, 0.68); outline: 0px; text-align: center; z-index: 300; --x-height-multiplier:0.342; --baseline-multiplier:0.22; font-family: medium-content-sans-serif-font, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Arial, sans-serif; font-weight: 400; font-style: normal; font-feature-settings: "liga", "lnum"; font-size: 16px; line-height: 1.4; letter-spacing: 0px;">MongoDB Compass GUI Interface</figcaption>
Before we dive into the coding part, you can checkout my github repository if you want to read the configuration in advance. Otherwise, you just need to follow the steps in order to get your project run.
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
<pre name="c7ba" id="c7ba" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">mkdir node-apis-project
cd node-apis-project
npm init </pre>
Step 2: Install all the dependencies
<pre name="4087" id="4087" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">npm install --save @types/express express body-parser mongoose nodemon</pre>
Step 3: Configure the TypeScript configuration file
The idea is to put all the TypeScript files in the lib folderfor 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.
<pre name="35e4" id="35e4" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"pretty": true,
"sourceMap": true,
"target": "es6",
"outDir": "./dist",
"baseUrl": "./lib"
},
"include": [
"lib/*/.ts"
],
"exclude": [
"node_modules"
]
}</pre>
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
<pre name="a5e1" id="a5e1" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">tsc</pre>
Step 4: edit the running scripts in package.json
<pre name="0d42" id="0d42" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">"scripts": {
"build": "tsc",
"dev": "ts-node ./lib/server.ts",
"start": "nodemon ./dist/server.js",
"prod": "npm run build && npm run start"
}</pre>
So, for the development, we can run a test server by running
<pre name="56be" id="56be" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">npm run dev</pre>
For production
<pre name="3c25" id="3c25" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">npm run prod</pre>
Step 5: getting started with the base configuration
You will need sooner or later the package body-parse for parsing incoming request data.
<pre name="fad5" id="fad5" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// lib/app.ts</pre>
<pre name="cdd1" id="cdd1" class="graf graf--pre graf-after--pre" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 0px; background: rgba(0, 0, 0, 0.05); padding: 4px 20px 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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());</pre>
<pre name="c741" id="c741" class="graf graf--pre graf-after--pre" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 0px; background: rgba(0, 0, 0, 0.05); padding: 4px 20px 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> //support application/x-www-form-urlencoded post data
this.app.use(bodyParser.urlencoded({ extended: false }));
}
}
export default new App().app;</pre>
Create lib/server.ts file
<pre name="a5ac" id="a5ac" class="graf graf--pre graf-after--p" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 43px 0px 0px; background: rgba(0, 0, 0, 0.05); padding: 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">// lib/server.ts</pre>
<pre name="7be8" id="7be8" class="graf graf--pre graf-after--pre" style="overflow: auto; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; margin: 0px; background: rgba(0, 0, 0, 0.05); padding: 4px 20px 20px; white-space: pre-wrap; color: rgba(0, 0, 0, 0.84); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import app from "./app";
const PORT = 3000;
app.listen(PORT, () => {
console.log('Express server listening on port ' + PORT);
})</pre>
From now, although you can not send a HTTP request yet, you still can test the project by running npm run dev.
This is the end of Part 1. I will update Part 2**, Part 3, Part 4 and **Part 5shortly. In case you need to jump a head. Please visit my github repository for the full code.