typescript+express+mysql로 간단한 웹 API 서버 만들기

MySQL+express+Type Script를 사용하여 만듭니다.
일시적으로 잘못된 처리를 고려하지 않다.
promise-mysiql을 사용했지만 mysiql2도 괜찮을 것 같아요.
소스 코드는 다음과 같습니다.
https://github.com/Msksgm/express_mysql_typescript_api

전체 구성


디렉토리 구조는 다음과 같습니다.
.
├── movies-ddl.sql
├── package.json
├── src
│   ├── app.ts
│   └── config
│       └── index.ts
├── tsconfig.json
└── yarn.lock

환경 구조


node.js


프로젝트 초기화
yarn init -y
install pakage
yarn add promise-mysql @types/mysql express
yarn add -D typescript ts-node @types/express @types/node
package.json에 다음과 같은 기술을 추가합니다
{
...
  "main": "src/app.ts",
  "scripts": {
    "build": "tsc",
    "start": "nodemon"
  }
...
}

데이터베이스


movie-ddl.sql 만들기
drop database if exists MOVIE;

create database MOVIE CHARACTER SET UTF8;

CONNECT MOVIE;
drop user if exists 'app-user'@'%';
set global validate_password_policy=LOW;
create user 'app-user'@'%' identified by 'PaAsW0rD';
grant all privileges on MOVIE.* TO 'app-user'@'%';

create table if not exists MOVIE
(
    ID                 serial primary key,
    NAME               varchar(100)                      not null,
    CREATED_AT         timestamp(3)    default current_timestamp(3) not null,
    UPDATED_AT         timestamp(3)    default current_timestamp(3) not null
);

INSERT INTO MOVIE(NAME)
VALUES ('天気の子');
INSERT INTO MOVIE(NAME)
VALUES ('サマーウォーズ');
INSERT INTO MOVIE(NAME)
VALUES ('ジョゼと虎と魚たち');
MySQL로 ddl 읽기
mysql -u root -p
# パスワードを入力
root@localhost> source /PATH/TO/express_api/movies-ddl.sql

.env 파일


환경 변수를 읽는 env 파일 만들기
완성하다.env 파일
# express
PORT=4000

# DB
DB_HOST="localhost"
DB_PORT="3306"
DB_USER="app-user"
DB_PASSWORD="PaAsW0rD"
DB_DATABASE="MOVIE"
읽기 명령
export $(cat .env | grep -v ^# | xargs)

이루어지다


config

src/config/index.ts
export default {
  /**
   * APIサーバーのPORT番号
   */
  port: parseInt(process.env.PORT, 10),

  /**
   * databaseの設定
   */
  db: {
    host: process.env.DB_HOST,
    port: parseInt(process.env.DB_PORT, 10),
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_DATABASE,
    multipleStatements: true,
  },
};

app

src/app.ts
import express from "express";
import * as mysql from "promise-mysql";
import config from "./config";

const app: express.Express = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.listen(config.port, () => {
  console.log(`Start on port ${config.port}.`);
});

const connection = async () => {
  return await mysql.createConnection(config.db);
};

// movie一覧取得
app.get("/movie", (req: express.Request, res: express.Response) => {
  connection()
    .then((connection) => {
      const result = connection.query("SELECT * FROM MOVIE");
      connection.end();
      return result;
    })
    .then(function (rows) {
      res.send(rows);
    });
});

// movie単一取得
app.get("/movie/:movieId", (req: express.Request, res: express.Response) => {
  const movieId = req.params.movieId;
  connection()
    .then((connection) => {
      const result = connection.query("SELECT * FROM MOVIE WHERE ID = ?", [
        movieId,
      ]);
      connection.end();
      return result;
    })
    .then(function (rows) {
      res.send(rows);
    });
});

// movie追加処理
app.put("/movie", (req: express.Request, res: express.Response) => {
  const name = req.body.name;
  connection()
    .then((connection) => {
      const result = connection.query("INSERT INTO MOVIE (NAME) VALUES (?)", [
        name,
      ]);
      connection.end();
      return result;
    })
    .then(function (rows) {
      res.send(rows);
    });
});

// movie更新処理
app.patch("/movie/:movieId", (req: express.Request, res: express.Response) => {
  const movieId = req.params.movieId;
  const name = req.body.name;
  connection()
    .then((connection) => {
      const result = connection.query(
        "UPDATE MOVIE SET NAME = ? WHERE ID = ?",
        [name, movieId]
      );
      connection.end();
      return result;
    })
    .then(function (rows) {
      res.send(rows);
    });
});

// movie削除処理
app.delete("/movie/:movieId", (req: express.Request, res: express.Response) => {
  const movieId = req.params.movieId;
  connection()
    .then((connection) => {
      const result = connection.query("DELETE FROM MOVIE WHERE ID = ?", [
        movieId,
      ]);
      connection.end();
      return result;
    })
    .then(function (rows) {
      res.send(rows);
    });
});

동작 확인


API 서버 시작


yarn start

CURD 확인


READ


전권을 얻다curl -H "Content-Type: application/json" localhost:4000/movie/ | jq
[
  {
    "ID": 1,
    "NAME": "天気の子",
    "CREATED_AT": "2021-06-03T23:39:19.024Z",
    "UPDATED_AT": "2021-06-03T23:39:19.024Z"
  },
  {
    "ID": 2,
    "NAME": "サマーウォーズ",
    "CREATED_AT": "2021-06-03T23:39:19.026Z",
    "UPDATED_AT": "2021-06-03T23:39:19.026Z"
  },
  {
    "ID": 3,
    "NAME": "ジョゼと虎と魚たち",
    "CREATED_AT": "2021-06-03T23:39:19.026Z",
    "UPDATED_AT": "2021-06-03T23:39:19.026Z"
  }
]
단일 획득curl -H "Content-Type: application/json" localhost:4000/movie/1 | jq
[
  {
    "ID": 1,
    "NAME": "天気の子",
    "CREATED_AT": "2021-06-03T23:39:19.024Z",
    "UPDATED_AT": "2021-06-03T23:39:19.024Z"
  }
]

CREATE


창설curl -X PUT -H "Content-Type: application/json" localhost:4000/movie -d ' {"name": "青の通り道"}'
{"fieldCount":0,"affectedRows":1,"insertId":4,"serverStatus":2,"warningCount":0,"message":"","protocol41":true,"changedRows":0}
확인curl -H "Content-Type: application/json" localhost:4000/movie/4 | jq
[
  {
    "ID": 4,
    "NAME": "青の通り道",
    "CREATED_AT": "2021-06-03T23:42:42.477Z",
    "UPDATED_AT": "2021-06-03T23:42:42.477Z"
  }
]

UPDATE


업데이트curl -X PATCH -H "Content-Type: application/json" localhost:4000/movie/4 -d '{"name": "新聞記者"}'
{
  "fieldCount": 0,
  "affectedRows": 1,
  "insertId": 0,
  "serverStatus": 2,
  "warningCount": 0,
  "message": "(Rows matched: 1  Changed: 1  Warnings: 0",
  "protocol41": true,
  "changedRows": 1
}
확인curl -H "Content-Type: application/json" localhost:4000/movie/4 | jq
[
  {
    "ID": 4,
    "NAME": "新聞記者",
    "CREATED_AT": "2021-06-03T23:42:42.477Z",
    "UPDATED_AT": "2021-06-03T23:42:42.477Z"
  }
]

DELETE


삭제curl -X DELETE -H "Content-Type: application/json" localhost:4000/movie/4 | jq
{
  "fieldCount": 0,
  "affectedRows": 1,
  "insertId": 0,
  "serverStatus": 2,
  "warningCount": 0,
  "message": "",
  "protocol41": true,
  "changedRows": 0
}
확인curl -H "Content-Type: application/json" localhost:4000/movie/ | jq
[
  {
    "ID": 1,
    "NAME": "天気の子",
    "CREATED_AT": "2021-06-03T23:39:19.024Z",
    "UPDATED_AT": "2021-06-03T23:39:19.024Z"
  },
  {
    "ID": 2,
    "NAME": "サマーウォーズ",
    "CREATED_AT": "2021-06-03T23:39:19.026Z",
    "UPDATED_AT": "2021-06-03T23:39:19.026Z"
  },
  {
    "ID": 3,
    "NAME": "ジョゼと虎と魚たち",
    "CREATED_AT": "2021-06-03T23:39:19.026Z",
    "UPDATED_AT": "2021-06-03T23:39:19.026Z"
  }
]

좋은 웹페이지 즐겨찾기