Express로 CRUD api 만들기 (01)

해당 시리즈는 한양대학교 정보시스템학과 2021학년도 2학기 데이터베이스시스템 수업 및 시험 대체 과제로 기획되었습니다.
  1. 시즌 399429호 블로그 엔진 만들기 결심
  2. 힙하게 Typescript 보일러플레이트 구성하기

일단은 데이터베이스는 생각하지 말고, 빠르게 express로 CRUD부터 만들어보자.
CRUD는 Create, Read, Update, Delete의 약자로, 대부분의 자료를 다루는 메소드 들이 이 범주내에 들어온다.

일반적으로 Create는 html의 POST로, Read는 html의 GET으로, Update는 PATCH로, Delete는 DELETE로 구현한다.

데이터 정의

유저 한 명에 대한 데이터는 다음과 같이 표현된다.

필드 설명 예시
id User 식별용 id. unique key. alphanumeric으로 이루어진다. "J9f3l0s7"
name User에게 표시되는 이름. unique key. UTF-8. "nick"
email User의 email 주소. "user@example.com"
tier User의 구독 정보. "default"

typescript의 interface로 나타내면 다음과 같다.

interface User {
  id: string;
  name: string;
  email: string;
  tier: string;
}

임시로 데이터베이스를 대신할 json파일을 생성하자. nick, lauren, david 3명의 유저를 만들어두겠다.

// user.sample.json
{
    "user": [
        {
            "id": "S8fs9jQ3",
            "name": "nick",
            "email": "nick@example.com",
            "tier": "admin"
        },
        {
            "id": "Q3J9d2j1",
            "name": "lauren",
            "email": "david@example.com",
            "tier": "default"
        },
        {
            "id": "Z3JnLm0s",
            "name": "david",
            "email": "david@example.com",
            "tier": "alpha"
        }
    ]
}

먼저 모든 유저 정보를 한 번에 확인할 수 있도록 route를 설정해주자.

// Route: /users (GET) - Return all users
app.get('/admin/users', (req: Request, res: Response) => {
  res.send(jsonFile)
})

http://localhost:{설정한 포트}/admin/users로 요청을 보내면, 위에서 생성한 json파일을 반환한다.

request

GET localhost:3624/admin/users

response

[
    {
        "id": "S8fs9jQ3",
        "name": "nick",
        "email": "nick@example.com",
        "tier": "admin"
    },
    {
        "id": "Q3J9d2j1",
        "name": "lauren",
        "email": "david@example.com",
        "tier": "default"
    },
    {
        "id": "Z3JnLm0s",
        "name": "hello",
        "email": "david@example.com",
        "tier": "alpha"
    }
]

CRUD 구성

생성(Create)는 보통 POST 메소드로 통신한다. POST는 값을 추가할 때 사용된다. 성공적으로 POST 통신이 이루어지면 응답으로 201 CREATED를 보낸다.

/users로 POST 메소드를 보내면 새로운 User를 생성하도록 한다.

// create method
// Route: /user (POST) - Create new user
app.post('/user', (req: Request, res: Response) => {
  const user = req.body
  user.id = nanoid(8)
  users.push(user)
  res.send(user)
})

request

POST localhost:3624/users

request body

{
    "name": "test",
    "email": "test@example.com",
    "tier": "test"
}

읽기(Read)는 보통 GET 메소드로 통신한다. GET은 값을 읽어올 때 사용된다. 성공적으로 GET 통신이 이루어지면 응답으로 200 OK를 보낸다. GET 통신 이후에는 원본이 변경되지 않아야한다.

// read method
// Route: /user/:id (GET) - Return user with id
app.get('/user/:id', (req: Request, res: Response) => {
  const id = req.params.id
  const userFounded = users.find((user: User) => user.id === id)
  if (userFounded) {
    res.send(userFounded)
  } else {
    res.status(404).send({ message: `User with id ${id} not found` })
  }
})

request

GET localhost:3624/users/S8fs9jQ3

response

{
    "id": "S8fs9jQ3",
    "name": "nick",
    "email": "nick@example.com",
    "tier": "admin"
}

수정(Update)는 보통 PATCH 메소드로 통신한다. PATCH는 값을 수정할 때 사용된다. 성공적으로 PATCH 통신이 이루어지면 응답으로 200 OK를 보낸다.

// update method
// Route: /user/:id (PUT) - Update user with id
app.put('/user/:id', (req: Request, res: Response) => {
  const id = req.params.id
  const userIndex = users.findIndex((user: User) => user.id === id)
  if (users[userIndex]) {
    const user = {
      ...users[userIndex],
      ...req.body
    }
    console.log(user)
    users[userIndex] = user
    res.send(user)
  } else {
    res.status(404).send({ message: `User with id ${id} not found` })
  }
})

request

PUT localhost:3624/user/Q3J9d2j1

request body

{
    "tier": "alpha"
}

response

{
    "id": "Q3J9d2j1",
    "name": "lauren",
    "email": "david@example.com",
    "tier": "alpha"
}

삭제(Delete)는 보통 DELETE 메소드로 통신한다. DELETE는 값을 삭제할 때 사용된다. 성공적으로 DELETE 통신이 이루어지면 응답으로 204 NO CONTENT를 보낸다. DELETE 통신 이후에는 다시 그 데이터에 접근할 수 없어야한다.

// delete method
// Route: /user/:id (DELETE) - Delete user with id
app.delete('/user/:id', (req: Request, res: Response) => {
  const id = req.params.id
  const userFounded = users.find((user: User) => user.id === id)
  if (userFounded) {
    const userIndex = users.findIndex((user: User) => user.id === id)
    users.splice(userIndex, 1)
    res.send({ message: `User with id ${id} deleted` })
  } else {
    res.status(404).send({ message: `User with id ${id} not found` })
  }
})

request

localhost:3624/user/Q3J9d2j1

response

{
    "message": "User with id Q3J9d2j1 deleted"
}

Reference

  1. https://peachsoong.tistory.com/20?category=880414
  2. https://daehopark.tistory.com/entry/NodeJS-JSON-파일-읽기
  3. https://memostack.tistory.com/180

Subscribe to jiwon.me

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe