---
title: Typescript Express + AWS PostgreSQL GraphQL
tags: Projects
---
# Build an app using Express in TypeScript, AWS PostgreSQL as database, Nuxt.js (Vue related framework) as frontend framework
## Set up backend part
* ```npm init -y```
* ```npm i typescript ts-node nodemon @types/node @types/express -D```
* ```npm i apollo-server-express express graphql type-graphql class-validator typeorm reflect-metadata```
* **typeorm is a kind of [Node.js ORM](https://juejin.im/post/6878138666683826190)**
---
### Install a database driver:
for MySQL or MariaDB
```npm install mysql``` (you can install mysql2 instead as well)
for PostgreSQL or CockroachDB
```npm install pg```
for SQLite
```npm install sqlite3```
---
### add "start" script
* about nodemon **--exec**, passing --exec tells nodemon to run a different program, instead of node. He's using ts-node as the executable since it's a TypeScript project. You can run and monitor other programs, such as python, ruby, etc. as well.
```Javascript=5
"scripts": {
"start": "nodemon --exec ts-node src/index.ts",
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
}
```
---
Now your package.json should looks like this
```Javascript=1
{
"name": "be",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon --exec ts-node src/index.ts",
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/express": "^4.17.9",
"@types/node": "^14.14.8",
"nodemon": "^2.0.6",
"ts-node": "^9.0.0",
"typescript": "^4.0.5"
},
"dependencies": {
"apollo-server-express": "^2.19.0",
"express": "^4.17.1",
"graphql": "^15.4.0",
"reflect-metadata": "^0.1.13",
"type-graphql": "^1.1.1",
"typeorm": "^0.2.29"
}
}
```
---
### add database
* create a PostgreSQL database on [AWS](https://towardsdatascience.com/creating-and-connecting-a-postgresql-database-with-amazons-relational-database-service-rds-dcc9db0cd37f)
* install database
```npm i pg```
* configure database
* add **ormconfig.json**
* most of the time you'll only need to configure ==host==, ==username==, ==password==, ==database== and maybe ==port== options.
```Javascript=1
{
"type": "postgres",
"host": "database-2.cravwavodaxd.ap-northeast-1.rds.amazonaws.com",
"port": 5432,
"username": "",
"password": "",
"database": "postgres",
"synchronize": true,
"logging": false,
"entities": ["src/entity/**/*.ts"],
"migrations": ["src/migration/**/*.ts"],
"subscribers": ["src/subscriber/**/*.ts"]
}
```
### initial git
```git init```
---
### ==BONUS== ESLint, Prettier and Husky
* install ESLint
`npm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard`
* configure ESLint
* add **.eslintrc.json**
```Javascript=1
{
"env": {
"es2020": true,
"node": true
},
"extends": ["standard"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": { "space-before-function-paren": "off" }
}
```
* install Prettier
`npm i -D --save-exact prettier`
* configure Prettier
* add .prettierrc.json
```Javascript=1
{
"semi": false,
"singleQuote": true,
"arrowParens": "avoid",
"printWidth": 120,
"trailingComma": "none"
}
```
* install Husky and pretty-quick
`npm i -D husky pretty-quick`
* configure Husky
In package.json, add:
```Javascript=1
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
}
```
* Timezone in PostgreSQL
`timestamptz` [note](https://docs.postgresql.tw/the-sql-language/data-types/date-time#zhu-yi)
MySQL doens't have `timestamptz`, also when you just type timestamp in MySQL, MySQL can get the right timezone.