--- 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.