[RESTful API] 어떻게 하면 좀 더 RESTful 해질 수 있을까?

2025. 1. 23. 23:21CS

 

 

개요

블로그 주인장은 API에 대한 기본적인 지식도 없이 백엔드 개발 좀 진행을 해보았다.

하지만 처음에 코딩을 할 때는 간단한 지식 밖에 없어서

URL 을 다른 API 이용자가 편하게 사용을 할 수 있도록 만들어야 된다고 생각만 했다.

 

그것이 어떤 방식이 있는지 찾아보지 않고 진행을 하였고

https://localhost:8443/get/userdata

이런 식으로 URL에서 어떤 뜻을 사용하는지 적어두었다.

당연히 사용한 HTTP method는 get과 post 밖에 사용하지 않았다.

 

이제는 Restful 에 대해서 알고 있지만, 옛날 같은 실수를 하지 않기 위해서

그리고 공부를 하던 도중 새롭게 알게 된 내용으로 어떻게 API을 만들어야 되는지 적어볼까 한다.

 

 


 

 

모든 것은 실수로부터 시작하고 배운다.

  • HTTP API 설계 - 잘못된 예시
router.post("/DBmain/__create", async (req, res) => {
  const jsonData = req.body;
  await __create(jsonData);
  res.send(200);
});

 

과거에 Express.JS를 가지고 코딩을 한 모습이다.

보면 코드에서 어떤 것을 하고 싶은지 알 수가 없다.

 

URL는 대문자가 있고, 어느 DB를 사용하지는 main DB라는 너무 추상적인 주체를 가리키고 있다.

그리고 언더바(_) 가 있고, jsonData는 RequestBody에서 어떤 값을 받는지에 대한 정보도 없고

DTO 같은 것을 사용해서 데이터를 걸러주는 모습 또한 없다.

마지막으로 돌려줄 때는 잘 되었다는 값 200만 보내 주는 모습이다.

 

 

이제 "RESTful을 어떻게 작성해야 하나?" 하기 전에 HTTP Method와 HTTP API 설계 방법에 대해서 알아보자.

 

 

 


 

 

HTTP Method 속성

HTTP Method 는 안정성(Safe), 멱등성(Idempotent), 캐시가능성(Casheable)의 3가지 속성을 지원한다.

  • 안전성(Safe)
    • Get 메소드(조회)는 안전하다. => 저장된 데이터를 변환하지 않는다.
    • Post, Delete, Put, Patch는 안전하지 않다. => 데이터를 저장, 수정, 삭제
  • 멱등성(Idempotent)
    • 한번을 호출하거나 수천번을 호출하거나 항상 결과는 같다.
      1. Get => 같은 결과가 계속 조회된다.
      2. Put => 수정해서 대체된 후의 결과는 계속 같다.
      3. Delete => 같은 요청을 여러 번 해도 삭제된 결과는 같다.
      4. Post => 멱등성을 보장하지 않는다. => 생성 같은 경우는 계속 같은 내용을 생성할 수 있기 때문에
    • 요청이 실패한 경우 재시도 하기위해서 필요하다.
  • 캐시가능성(Casheable)
    • 재사용성을 위해 요청에 대한 응답을 저장할 수 있는가?
      1. Get, Head, Post 메소드는 캐시가 가능하다.
      2. 일반적으로 Get, Head 정도만 캐시로 사용한다.

 

 

HTTP API 설계 방법

  1. 항상 리소스 식별을 기준으로 삼아야 한다.
  2. URI에 들어갈 리소스는 복수형태로 사용한다.
  3. URL에 동사를 사용하지 않는다.
  4. HTTP 메서드의 역할을 URL에 포함하지 않는다.

 


 

 

과거에 잘못 만든 것을 수정을 해보자.

  • HTTP API 설계 - 잘못된 예시
router.post("/DBmain/__create", async (req, res) => {
  const jsonData = req.body;
  await __create(jsonData);
  res.send(200);
});

 

위의 예시에서 잘못된 점을 집어보자.

  1. DBmain는 이름부터 잘못되었기 때문에 수정해야 한다. 하나씩 집어보자.
    • DBmain은 이름이 너무 추상적이다. 해당 DB의 리소스는 movie 이므로 movies로 바꾸면 될 것 같다.
    • movie는 단수이므로 복수형태로 movies로 바꿔야 한다.
    • __create는 동사이기 때문에 없애야 한다.
  2. jsonData는 너무 추상적이기 때문에 수정을 하자.
    • 여러 영화를 받아서 저장을 하는 것이기 때문에 jsonData가 아니라 movies를 받는 것으로 하면 될듯하다.
  3. __create라고 하면 뭔가 만드는 느낌이니 저장을 하는 영어단어인 save로 바꾸면 될듯하다.
  4. 너무 단순하게 status만 보내는 느낌이니 잘 저장이 되었다는 말도 보내자

 

  • HTTP API 설계 - 수정
router.post("/movies", async (req, res) => {
  const movies = req.body; // json 배열 받기
  await save(movies);
  res.status(200).send('success');
});

 

아예 추상적이었던 API을 이제 이해가 가능하게 바뀐 듯하다.

 

이제 기본을 배웠으니 RESTful API에 대해서 배워보자.

 


 

RESTful API란?

제가 다니고 있는 내배캠의 튜터님이 자세하게 정리를 해준 내용이 있어 가져와봤습니다.

REST를 잘 준수하는 API로 HTTP을 사용하여 클라이언트와 서버 간의 통신을 통해 자원(Resource)을 관리한다. 자원은 고유한 URI로 식별되며, HTTP 메소드(GET, POST, PUT, DELETE 등)를 통해 다양한 작업을 수행하며 요청과 응답은 일반적으로 JSON 또는 XML형식으로 이루어진다.

=> REST 기반으로 서비스 API를 구현한것, HTTP API를 잘 설계하는 규칙이라고 정리할 수 있다.

 

REST(Representational State Transfer)란 ?

자원(Resource)을 이름(Name)으로 구분하여 해당 자원의 상태(정보)를 주고받는 것을 의미한다.

=> URI을 통해 자원(Resource)을 명시하고, HTTP Method(GET, POST, PUT, DELETE 등)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 REST라 칭한다.

 

REST API URI 명명 규칙 및 모범 사례

  1. 리소스는 명사를 사용해야 한다.
  2. 단수가 아닌 복수 형태를 사용해야 한다.
  3. 만약, REST만으로 해결하기 어려운 경우라면 동사를 허용한다.
  4. 자원의 계층 관계를 슬래시(/)로 표현한다.
  5. 마지막 문자에는 슬래시(/)가 있으면 안된다.
  6. 언더바(_)가 아닌 하이픈(-)을 사용해야 한다.
  7. 소문자를 사용해야 한다.
  8. URI에 파일 확장자를 포함하면 안된다.
  9. CRUD 함수명은 사용하지 않고, HTTP Method를 활용해야 한다.
  10. 정렬, 필터링, 페이징은 신규 API를 만드는것이 아닌 Query Parameter를 사용해야 한다.

 

위의 내용 원본 자료

 

REST API URI Naming Conventions and Best Practices

In REST, having a strong and consistent REST resource naming strategy – will prove one of the best design decisions in the long term. Let's discuss.

restfulapi.net

 

위의 내용에 추가하여 Richardson Maturity Model 또한 알아야하지만 이 내용은 다음에 포스팅 해보는 것으로 하겠다.

 

 


 

이제 RESTful하게 만들어보자

URI HTTP 동사 작업
/DBmain/__create POST 영화 목록 저장하기
/DBmain/__read GET 영화 정보 가져오기
/DBmain/__update PUT 영화 정보 수정하기
/DBmain/__delete DELETE 영화 삭제하기

 

전에 만들어보았던 프로젝트 API 일부를 가져와보았는데, 확실히 옆에 작업 목록이 없다면

어떤 내용인지 확인을 하기가 많이 어렵다.

 


 

예시로 영화 서비스를 만든다고 해보자.

  • 영화 목록 가져오기
  • 영화 정보보기
  • 영화 삭제하기
  • 영화 예약 추가/취소하기

 

RESTful API 의 기준을 맞춰서 만들어 보았다.

URI HTTP 동사 작업
/movies GET 영화목록 가져오기
/movies/{id} GET 영화 정보 가져오기
/movies DELETE 영화 삭제하기
/reservations POST 예약 추가

 

전에 만들었던 영화 프로젝트보다 훨씬 보기 편한 모습을 확인할 수 있다.

 

마지막으로 고려사항에 대해서 알아보고 마무리 하려고한다.

 


 

 

RESTful API 설계 시 고려해야 할 사항들

1. Consumer first

  • 개발자 중심의 설계방식보다 해당 API의 소비자 입장에서 간단하고 직관적인 API를 설계 해야한다.
  • 위에서의 소비자는 엔드유저가 아닌 API를 사용 하고있는 또다른 시스템, 개발자 등을 얘기한다.

2. Make best use of HTTP

  • HTTP Method와 Request, Response, Header와 같은 HTTP의 장점을 살려서 개발 해야한다.

3. Request methods

  • 최소한 성숙도 모델 Level2로는 사용하여야 한다.

4. Response Status

  • 각각의 API 요청에 따라서 적절한 HTTP 상태코드가 전달되어야 한다.
  • 성공했다, 실패했다가 아닌 왜 실패하고 성공 하였는지 함께 반환 시켜주어야 한다.

5. No secure info in URI

  • URI에는 사용자의 정보를 포함해서는 안된다.

6. Use plurals

  • 제공하는 데이터에 대하여 단수가 아닌 복수형태로 쓰는것이 일반적이다.
  • 특정 유저를 찾고자 한다면 엔드포인트에 값을 추가한다.
    • ex) /user -> /users
    • ex) /users/1

 

7. User nouns for resources

  • 모든 리소스는 가능하면 동사가 아닌 명사형태로 표시한다.
  • API URI만 보고도 어떠한 API인지 파악할 수 있는것이 좋다.

8. For exceptions - define a consistent approach

  • 일괄적인 엔드포인트를 사용하는것이 좋다.

 

 

느낀점

매번 프로젝트를 진행을 할 때마다 API는 단순해야 된다고만 생각을 하였다

근대 항상 보면 마지막에는 내 기준이 되어있는 모습을 확인을 할 수 있었다.

 

나중에는 불편한 점을 알고 스스로 RESTful API 규칙을 찾아서 공부를 하였는데

이번에 내배캠에서 강의로 해당 내용을 들으니까 이것은 꼭 블로그로 적어놓고 기억을 해야겠다는 생각이 들었다.

 

이미 저질러놓은 프로젝트들에서 많은 실수를 했고 배웠고, 이번에도 더 자세하게 배웠다.

이것이 나에게 팀프로젝트에 있어서 많은 도움을 줄 것이라 생각한다.