Building and running a Node.JS, TypeScript, PostgreSQL app with Docker

Derek Ji
3 min readSep 3, 2020

Creating a Node.JS application

I assume you have installed Node.JS before. Creating every Node.JS application starts with a simple command npm init If you add -y , it will fill all input for you and create a package.json file necessary for managing our application dependencies required for it to run.

Since we said we’re going to use TypeScript, we have to set up our project to work with TypeScript right away.

Next, we’ll install TypeScript and tslint in our project by typing the following:

npm install typescript tslint --save-dev

This command will install TypeScript in our dev dependencies. After we have installed TypeScript, we’ll edit our package.json file and add tsc command for accessing TypeScript commands. We'll be using this command for starting and bundling our application.

After we’ve installed these packages, we’ll run the following command to initialize our tsconfig.json file where compiler options for our project are stored.

Since we’ll be using Express, it’s important to install a package that helps TypeScript identify express types by typing:

npm i @types/express @types/node --save-dev

This way, TypeScript will be able to recognize Express classes and global Node types. For example, after you install the types package, you’ll be able to import Request and Response types from Express directly.

If we initialize tsconfig.json with the first command, we’ll get a file like this:

This is our tsconfig.json file with plenty of compiler options you can customize.

We’ll replace it with the following:

{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist/src"
},

We are mostly interested in our outDir property where we specify the output directory for our transpiled TS code into JS.

Creating and starting our server using TypeScript

It is always a good idea to separate your scripts for defining your server and start your application using that server configuration.

For now, our project structure looks like this:

I’ve created dbconfig directory with database configuration that we’ll use when initializing thePostgres connection.

In the server.ts file lies our server configuration looking like this:

We’ll explain the configuration as we go. Firstly, we initialize our Express application, move to server specific configurations such as configuringbody-parser to handle our incoming data. In the end, there is a public method we’ll use to start our server in our app.ts file. We also set up our routing to use separated router configuration for getting all todos.

Here we call our “start” method and log in case of success or failure.

Postgres configuration

Pooling is a process of creating connections and caching them to reuse them. There is no resource waste as it would be if you create a new connection every time.

Below is the explanation of the mentioned configuration properties :

I am using pgAdmin4 for accessing my database cluster and managing my databases.

TodosController

We’ll create a TodosController and route for fetching all todos from the database.

A controller would look like this:

  • Importing pool from our database configuration class
  • Initializing new connection and creating an instance of pg client
  • Sending our raw query to our client’s query method — async
  • Releasing our connection -THIS IS IMPORTANT!
  • Returning fetched data

Always release your connection when using the pool. That way, the client will return to the pool of available connections.

Todos router

We’ll set up our router in a separate file stored in src/routers and give it a route to the GET method defined upper in our TodosController.

Now, all we have to do is register this router in our server.ts where we set up our server.

We import our todos router and we say to our Express server that anytime someone hits “/todos” in the URL, pass the instance todosRouter to handle all the requests with that route.

Originally published at https://medium.com on September 3, 2020.

--

--