October 21, 2018

My experience in writing a REST service using TypeScript + Express

This story is also published here: https://dev.to/sanijalal/my-experience-in-writing-a-rest-service-using-typescript--express-5aml

I'm here to share my experience as a .NET WebApi developer trying to write a REST service using TypeScript + Express. Here we go!

So let's start with creating a github repo for this. Here we go: https://github.com/sanijalal/dailydiaryservice

Then, lets setup our app by running npm init.

npm init

I have no idea how to test on typescript yet, so I'll ignore that first. I have no idea what is ISC license, so let's just go with that for now(let's hope it doesn't include a clause that sells my soul to the devil).

What's next? So I know I want to use TypeScript. Let's install that.

npm install typescript

I also know that I want to use Express. So let's install that.

npm install express

Now we get things going. We have TypeScript and Express installed in the project. What should we do next now?

Okay, for starters. I don't know how Express works. Let me google for a bit how to use express.

After googling..

Okay, I read about how Express works.[https://medium.com/@LindaVivah/the-beginners-guide-understanding-node-js-express-js-fundamentals-e15493462be1] But this is using javascript. I want to write TypeScript.

Huh, I don't know TypeScript.

Let's Google that.

Okay, after reading this [https://code.tutsplus.com/tutorials/typescript-for-beginners-getting-started--cms-29329] I think I've got the hang of typescript.

  1. I need to call tsc when I want to transpile my code from typescript to javascript.
  2. I need to have a tsconfig.json file in my project to tell typescript how to convert my typescript files to javascript.

Let's sort out step 1. I'm going to create a build script which calls tsc. How do I do that? Let's add this in our script part in package.json

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "tsc"
  },

So when we call npm run build we will transpile the TypeScript to javascript.

But we haven't told TypeScript which folder to get the TypeScript files. Let's do number 2 now. Let's create a tsconfig.json file. I'm going to use this tsconfig values from this tutorial[https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-1-2-195bdaf129cf]

// tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "moduleResolution": "node",
        "pretty": true,
        "sourceMap": true,
        "target": "es6",
        "outDir": "./js", // Javascript files will be created in this directory. Include this folder in .gitignore to not add it to git.
        "baseUrl": "./src"
    },
    "include": [
        "src/**/*.ts" // The ** means all files and folder in the src folder. People call it recursive. The *.ts means all files that end with .ts will be picked up.
    ],
    "exclude": [
        "node_modules"
    ]
}

Ok now when we call tsc, TypeScript will convert all typescript files in the src folder to javascript files in the js folder.

Let's also add a start script to our package.json.

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "tsc",
    "start": "node js/app.js"
  },

Apparently I also need to install @types/express to tell register the definitions for express in TypeScript(I think). Let's do that

npm install @types/express

Okay, let's write our Express code in src/app.ts!

import express = require("express"); // We need to import the express package.

// 1) This is how set up our express app. Initialise an express instance.
const app = express();
app.set("port", 1337); // 2) We need to setup which port to listen to. I use 1337.

// 3) This registers the get endpoint with the / uri. req is the request we receive. res is what we are sending.
app.get('/', (req, res) => {
    res.send("Hi")   // 4) Here we are sending the Hi message when we hit this endpoint.
})

// export our app
export default app; // 5) To let other files use this class, we need to export it.

Okay, if I write it this way. We need to have a server.ts file as well. Let's change our package.json again to call server.js instead of app.js in our start script.

    "start": "node js/server.js"

Ok, let's write our server.ts file now! Looking into the example in [https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-1-2-195bdaf129cf], this is what we are going to write:

// server.ts
import app from './app' // 1) We need to import the app class we created previously.

// 2) This creates the server which is listening to the port number we defined in the app class.
const server = app.listen(app.get("port"), () => {
    console.log(
        "App is running on http://localhost:%d in %s mode",
        app.get("port"),
        app.get("env")
    ) // 3) We are going to put this in console so you can see that it is actually working.
});

export default server;

Now that we have done this, let's build our app! Run this command in terminal.

npm run-script build

You will see that javascript files are now generated in the js folder. Fancy eh? Let's start this app now.

npm run start

You will see this in the console: App is running on http://localhost:1337 in development mode

Yay! We have our app running! Open the url in a browser and you will see Hi! This is what we wrote earlier in our app.ts

// app.ts
// We wrote this earlier!
// ...
app.get('/', (req, res) => {
    res.send("Hi")   // 4) Here we are sending the Hi message when we hit this endpoint.
})
// ...

Ok, now we have the app running, how do we stop it? I am not ashamed to admit that when I first started learning terminal commands, I didn't know how to stop this. But it's actually simple. Press ctrl + c. This will kill the process and your server will now stop.

Yay! We have a service that does nothing. At least not yet. In the next post we will implement endpoint routing using express router.

Thank you for reading!