[첫번째 프로젝트] RESTful API란?

노력을 즐겼던 사람·2020년 4월 24일
1

나의 프로젝트는 RESTful한가?

첫 프로젝트를 완성하고 프로젝트를 천천히 분석하는 시간을 가지고 있다. 프로젝트를 진행할 때 RESTful API로 구현했다. 그렇다면 나는 REST API가 뭔지 알고 있는가? 내가 아는 RESTful API는 이렇다.

  • 웹 뿐 아니라 여러 플랫폼에서 모두 사용할 수 있는 서버이다.
  • HTTP Method를 사용한다.
  • JSON을 사용한다.

대충 이렇게만 알고 있었다. RESTful API가 무엇인지 정확히 알지도 못하면서 남들이 다 RESTful API를 사용하니까 비슷하게 흉내만 냈다. 이번 기회에 RESTful API가 무엇인지 그리고 내 프로젝트를 RESTful API에 맞게 리팩토링하는 시간을 가져보려고 한다. 그 전에 지피지기면 백전백승이라고 했다. REST API가 어떤 녀석인지 확실히 짚고 넘어가자.

REST API란?

Respresentational State Tranfer의 약자이다.

자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미한다.

자원을 이름으로 구분한다 는 뜻을 살펴보자면 자원 은 통신을 통해 주고 받는 데이터이다. 나의 프로젝트에 대입하여 생각해보자면 회원가입 때 입력 받는 아이디, 비밀번호, 이름, 학번으로 생각할 수 있겠다. 서버 측에서 클라이언트에 제공하는 데이터들도 자원이다. 마찬가지로 나의 프로젝트에 대입하여 생각해보자면 스프링 JAR 파일 그 자체도 자원에 해당한다. 그렇다면 이제 이름 을 살펴보자 이름은 간단하다. 자원을 표현하기 위한 이름이다. DB에 저장되는 변수명도 될 수 있고 URL에도 이름을 등록할 수 있다.
자원의 상태를 주고받는 다는 뜻을 살펴보자. 자원의 상태 는 HTTP Method라고 할 수 있다. 필자의 프로젝트에서는 CRUD를 구현하기 위해서 GET, POST를 사용했다.

REST API의 특징

  • Uniform Interface
    REST는 HTTP 표준에만 따른다면 어떠한 기술이라던지 사용이 가능한 인터페이스 스타일이다. 내가 REST를 대략 알고 있던 내용이다. 웹 뿐 아니라 여러 플랫폼에서 사용할 수 있다는 말이다. Android, iOS와 같은 다양한 플랫폼, C/JAVA/PYTHON 등과 같은 언어에도 종속 받지 않는다.

  • Stateless
    말 그대로 상태를 유지하지 않는다. 사용자나 클라이언트의 context를 서버 쪽에 유지하지 않는다는 의미이다. HTTP Session과 같은 context storage에 상태 정보를 저장하지 않는 형태를 의미한다. 필자의 수준에서는 Stateless 특징이 어떤 효과를 불러오는지 가늠이 안가지만 참고한 문서에서는 이러한 장점을 제시하고 있다.

    상태 정보를 저장하지 않으면(Sateless) API 서버는 들어오는 요청만을 메시지로만 처리하면 되며, 세션과 같은 context를 신경 쓸 필요가 없기 때문에 구현이 단순해진다.

  • Cacheable
    Uniform Interface에서 언급한 것과 같이 REST는 HTTP 표준을 그대로 사용하기 때문에 웹에서 사용하는 기존의 인프라를 그대로 Caching해서 사용할 수 있다. HTTP 기반의 Load Balancer, SSL, HTTP Caching을 적용할 수 있다. 필자의 수준에서는 Cacheable 특징이 어떤 효과를 불러오는지 가늠이 안가지만 참고한 문서에서는 이러한 장점을 제시하고 있다.

    일반적인 서비스 시스템에서 60%에서 많게는 80% 가량의 트랜잭션이 Select와 같은 조회성 트랜잭션이기 때문에 HTTP의 리소스들을 Caching하는 것은 용량, 성능면에서 많은 장점을 가지고 올 수 있다.

  • Self-descriptiveness(자체 표현 구조)
    REST API는 매우 쉽기 때문에 API 메시지 자체만 보고도 API를 이해할 수 있는 Self-descriptiveness 구조를 갖는게 특징이다. 리소스와 메서드를 이용해 어떤 메서드에 무슨 행위를 하는지를 알 수 있으며 메시지 포맷 역시 JSON을 이용해서 직관적으로 이해가 가능하다. 뒤에 언급하겠지만 필자는 자체 표현 구조를 잘못이해해서 REST 안티 패턴으로 프로젝트를 구현했다.

REST 안티 패턴

REST API를 디자인할 때 하지 말아야 할 안티 패턴을 나열해보고 필자의 프로젝트에서 안티 패턴들을 찾아서 제거해보고자 한다.

  • GET/POST를 이용한 터널링
    예를 들어서 설명하자면 자원을 업데이트 하는 경우에는 PUT을 사용해야한다. 그런데 이를 따르지 않고 GET, POST를 사용하는 경우를 말한다. 게다가 GET 메소드를 사용하면서 URL에 쿼리 파라미터로 method=update와 같이 명시하는 경우에 대단히 나쁜 디자인이라고 말한다. 이유는 HTTP 메서드 사상을 따르지 않았기 때문에 REST라고 볼 수 없고 웹 캐쉬 인프라 등도 사용이 불가능하다.

    GET을 사용한 터널링
    HTTP GET, http://myweb/users?method=update&id=terry

    POST를 이용해 JSON body에 하고자 하는 행위의 이름을 작성하여 넘기는 경우이다.

    POST를 사용한 터널링
    HTTP POST, http://myweb/users/
    {
    "getuser":{
    "id":"terry".
    }
    }

위의 예시는 POST를 Create할 때 사용하지 않고 Read할 때 사용을 하며 JSON body에 getuser라는 행위의 이름을 작성하여 넘겼다.

  • Self-descriptiveness 속성을 사용하지 않음
    REST는 REST URI, HTTP Method, 정의된 메시지 포맷을 보고 쉽게 API를 이해할 수 있도록 디자인해야한다. GET,POST를 사용한 터널링 구조가 가장 대표적으로 Self-descriptiveness를 어기는 대표적인 사례이다.

  • HTTP Response code를 사용하지 않음
    말 그대로 HTTP Response code를 사용하지 않는 것이다. HTTP Response code는 REST API를 쉽게 이해할 수 있도록 도와준다.

내 프로젝트는 안녕한가?

필자의 프로젝트는 RESTful 하지 않다. update할 때 POST를 사용했고 delete할 때 GET을 사용한 것도 있다. 혹은 URI만 보고 알아볼 수 있게 만들어야한다는 생각에 사로잡혀 URL 설계 또한 엉망이다. 심지어 HTTP Response code는 단 한번도 사용하지 않았다. static final double을 이용해 상수를 선언하고 상수명으로 에러를 구분했다. 이렇게 에러를 구분 했을 시 클라이언트, 서버 둘 다 에러를 등록해줘야 하는 번거로움이 있었고 만약 개인 프로젝트가 아닌 팀 프로젝트였다면 나의 코드를 다른 개발자가 알아보기 힘들었을 것이다. 다음 포스팅에서는 필자의 프로젝트를 RESTful하게 리팩토링을 할 예정이다.

참고 문서

조대협님 블로그 - https://bcho.tistory.com/953
heejeong Kwon님 블로그 - https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html

profile
노력하는 자는 즐기는 자를 이길 수 없다 를 알면서도 게으름에 지는 중

0개의 댓글