Building an API Backend with TypeScript and Express - Part One: Setup
https://www.worl.co/2016/12/building-an-api-backend-with-typescript-and-express---part-one-setup/
TypeScript gives JavaScript developers a much-needed type-safe option for front-end development, but it works just as well in a Node environment. Node even includes many next-generation JavaScript features that older browsers don’t ship, so you won’t need any post-processing tools like Babel or Webpack/Browserify. In this tutorial I will assume you have a basic understanding of the command line and have a recent version of Node and NPM installed. I would also recommend using Visual Studio Code because it has good out-of-the-box support for TypeScript.
We’re going to build a basic backend API with Node and TypeScript. We’ll use the popular Express web framework for the basic building blocks. In future posts, we’ll expand into database persistence, code organization, advanced TypeScript features, and more. In this post, we’ll just cover getting our TypeScript environment set up and creating a “Hello World!” route with Express.
If you don’t already have TypeScript installed, you can install it with npm install -g typescript
in a terminal. At the time of writing, the current stable version is 2.1.
Now we can get started! cd
into wherever you’d like to store this project, and run mkdir ts-express; cd ts-express
. Then run npm init
to create the package.json
file describing the application. You can leave the defaults as they are.
You now have all the of the basic scaffolding to get started with TypeScript. It works very similarly to any other Node project, and your general workflow will be the same as a regular JavaScript project. We can now install our dependencies from NPM.
npm install --save express body-parser
Because these are JavaScript libraries, we need TypeScript definition files to get the full benefit of type-checking when we use them. These definition files declare the module layout and exported types for each library. You can install the definitions for Express and the body-parser middleware like this:
npm install --save @types/express @types/body-parser
Now let’s write some TypeScript! Open up your editor of choice into the ts-express
directory and start by creating a src
directory. This directory will hold our TypeScript code. Later we’ll configure where the TypeScript compiler should output our code. Once you’ve created the src
directory, create a new file called app.ts
. We’re going to place all our code in this file to start with and learn more about code organization later.
As a base, we’ll start with a simple JavaScript version and slowly convert it to TypeScript. All valid JavaScript is valid TypeScript. If you have a legacy JavaScript project to convert, you can start by changing all the file extensions from js
to ts
and incrementally adding types until you’re satisfied. Any compiler errors about types when compiling this un-typed code are really more like warnings: the TypeScript compiler just keeps going.
// src/app.ts
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.send('Hello World!');
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
});
This code starts an Express server, adds one root route, then starts listening on port 3000. That’s about as stripped-down as you can get. Now let’s compile it!
$ tsc src/app.ts
Obviously compiling all our files one at a time as we write more code is not pleasant, and we definitely don’t want our compiled JavaScript sitting next to our TypeScript files. The TypeScript compiler has a configuration file to let us fix that.
Here’s the tsconfig.json
file I’m going to use for the remainder of this project. Put it in the root of the project.
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": false,
"removeComments": true,
"preserveConstEnums": true,
"outDir": "build",
"strictNullChecks": true,
"sourceMap": true,
"target": "es2015"
},
"include": [
"src/**/*"
],
"exclude": [
"**/*.spec.ts"
]
}
I’ve highlighted the important options. outDir
tells the compiler to output our compiled code into a directory named build
. Don’t worry about creating it, the compiler will do that for us. strictNullChecks
forces us to be correct about knowing if any of our variables can be null, which will save you some annoying debug time later when something is unexpectedly null or undefined. target
tells the compiler to compile our code into ES2015 JavaScript syntax. Other options include ES3 and ES5, which you would most likely use when targeting browsers because of their more limited feature set. In general, TypeScript tries to support as many previous versions as are reasonable and possible for their advanced features like async/await
.
Now you can compile with tsc
and, hopefully, not receive any errors. Your code will output into the build
directory as specified in tsconfig.json
. You can now run the code:
$ tsc
$ node build/app.js
Example app listening on port 3000!
That’s all for this section! The next section will explore TypeScript’s type-checking, defining different routes, and validation.