POST Method는 데이터의 생성부분을 담당한다. 다시 말하면, 데이터 조회의 조건이 필요없다는 말이다.
생성 대상이 되는 Data Set에 대하여 새로운 데이터의 내용을 채워주면 된다.
POST /dataset --data '새로운 데이터의 내용'
즉 사용자에 대한 dataset이 user이고, 채워야 하는 내용이 id, pw, name이 전부라면 다음과 같은 생김새를 갖게 된다.
POST /user --data '{"id":"gildong", "pw":"password", "name":"홍길동"}'
Data Set은 URI, 데이터 내용은 Body Parameter
간혹가다 사설 RESTful API의 경우 Body Parameter를 Query String으로 보내는 경우가 있는데, 어.. 매우 좋지 않다. Query String으로 보낼 경우, 외부에 노출되기 때문에 보안적 측면에서 매우매우 아주아주 좋지 않은 구현이다.
사용자 로그인 기능을 구현할 때, 사용자 정보를 Body Parameter에 담아서 보내는 것을 생각하면, 그 이유를 떠올리기 쉬울 것이다.
Body Parameter는 JSON Type으로!
Body Parameter는 어느 플랫폼에서 보내느냐에 따라 획득할 수 있는 방법이 다르다. Nodejs 즉 React에서 전송된 데이터와 JSP를 통해 전송된 데이터를 구하기 위한 방식에 약간의 차이가 있기 때문에, (적어도 Java의 Dynamic Web Application은 그러했다.) 될 수 있으면 데이터 생성 요청에 대한 컨텐츠 타입을 미리 서버에서 JSON만 허용하도록 설계해 놓는게 편하다.
따라서 우리가 편하게 데이터를 조작할 수 있는 JSON Type으로 요청을 받도록 하는게 제일 좋다.
글이 짧아서 실망했을 수 있는데, 데이터 조회를 제외하고는 우리가 흔히 했던 일반적인 API를 설계하는 것과 비슷하다. 다만 RESTful API라는 객체의 입장에서 다른 부가기능적인 요소를 생각해야 하고, 그것은 POST Method를 설계하기 위해 필수조건이 아니기 때문에 오늘 POST Method의 설계는 여기서 마치겠다.
그렇다고 해서 다른 Methods에서 다 되는데 POST만 안되게 하라는건 아니다. 다만 POST의 의무가 아닌 RESTful API 객체의 의무라는 뜻이다.
GET /getUsers?name={name}&user_SEQ={seq}&type={type}&print={print}
2. URI Segment
GET /users/name/{name}/user_SEQ/{seq}?type={type}&print={print} 사실 이 방식은 MkWeb을 설계하면서 고안한 방법이고, 앞 글을 보면 내가 준 팁에 그대로 나와있다.
앞서 말한것 처럼 RESTful API는 URI Segment를 지향하고, 주소에 데이터 관련 조작 방식을 나타내지 않는게 좋기 때문에 2. URI Segment방식을 활용하여 설계하는 것이 좋다.
하지만 바로 전 글에서 말한것 처럼 꼭 이를 지킬 필요는 없다. ElasticSearch의 RESTful API같은 경우에는 QueryString중 q 파라미터를 통해 데이터를 조회하는것 처럼, 내가 잘 설계하고, 사람들에게 잘 지침을 주면 된다.
MkWeb의 경우에는 다음과 같이 설계 했다.
/DATASET/조건1/{조건1값}/조건2/{조건2값}/...?OPTIONS
먼저 데이터 셋을 정의해라
어떤 RESTful API든 간에 우리가 조회하고자 하는 대상이 있다. 해당 대상에 대한 데이터 셋을 먼저 정의하고, URI의 최상단에 선언하자.
그렇게 되면, 우리가 조회하고자 하는 데이터가 무엇인지 한눈에 보기 쉽기 때문이다.
데이터 셋을 정의할 때는, 여러개의 데이터를 하나로* 묶을 수 있고, 한 API당 하나의 데이터만**을 조회하게 할 수 있다.
MkWeb에서는 한 API당 하나의 데이터만을 조회하게 했는데, 이미 MkWeb에서 지원하는 다른 SQL Method에서 여러 데이터를 하나로 묶은 결과를 받을 수 있기 때문이었고, 큰 이유는 API는 데이터를 조작하기 위함인데, 여러 데이터를 통합했을 때 발생하는 데이터는 이러한 목적, 즉 이미 조작된 데이터이기 때문에 약간 다르다고 생각했기 때문이다.
*여러개의 데이터를 하나로: 유저정보 + 직장정보
**한 API당 하나의 데이터: 유저정보, 직장정보 각각 따로
데이터 조건들은 모두 Key-Value 쌍을 이루게 하자
RESTful API를 처음 설계할 때, 다음과 같은 설계를 허용할지 엄청 고민했다.
GET /users/name MkWeb 자체가 범용적인 사용이 가능하기를 바랬고, 그렇기 때문에 발생한 고민이었는데 결국 의미 없는 고민이었다.
해당 요청의 목적은 요청에 대한 응답이이름만 반환하기를 바랬던 것인데, 이는 사용자가 요청부분에서 담당할게 아니라, 응답하기 위한 데이터 셋에 name만 반환하도록 설계하면 되는 것 이었다.
딴 말이 길었는데, 조건들이 Key-Value 쌍을 이룸으로써 어떤 데이터 셋에 대한. 조회를 할 때, 정확한 데이터만 집을 수 있도록 함이다. 물론 정확한 데이터, Unique하지 않은 필드의 조회에 대해서는 그 결과에서도 겹치는 부분이 많을 것이다. (동명이인과 같이)
그렇지만, 적어도 쌍을 이루게 함으로써 조회의 정확도를 높이고, RESTful API의 설계 난이도를 낮출 수 있다.
API 조건은 모두 Query String으로
URI Segment에 조회하고자 하는 데이터 셋을 특정짓고, 검색 옵션을 모두 Query String에 넣음으로써 우리는 무엇이 데이터와 관련된 조건이고, 응답에 대한 옵션인지를 한눈에 파악할 수 있다.
API 조건은 예를 들어, 응답을 특정 방식으로 정렬하기를 바라거나, 데이터 조회시 20개만 가져오길 바라는 등, 검색하고자 하는 데이터를 특정하지는 않지만, 데이터 조회에 영향을 미치는 부가 기능을 의미한다.
1.Query String처럼 한곳에 데이터 검색을 위한 조건과 옵션을 모두 때려 넣으면, 어느 것이 데이터 조건이고, 부가기능인지 헷갈리기 때문이다.
그래서 설계를 어떻게 해야 하는가?
사실 많은 사람들이 설계를 어떻게하는지 보기 위해서 이 페이지에 들어왔을거라 생각한다. 나도 처음 RESTful API를 접했을 때 많은 고민을 했고, 특히 MkWeb의 특징을 살리기 위해 가능한 모든 방안을 수용 가능하도록 만들려고 했다. 하지만 RESTful API인 것 처럼, 그리고 이미 RESTful API의 설계에 대해 고민을 해봤다면, 의미 없는 질문인 것을 알 수 있다.
결국, RESTful API를 설계하기 위한 방법론, 즉 설계도면을 구하고자 하는 것이지, 이미 설계도면을 구한 상태에서 설계를 어떻게 해야하는가 하는 질문은, 건축하기 위한 설계도를 구했으나, 내부 자재는 어떤걸 쓸지, 드릴질은 몇번 할지를 묻는것과 같기 때문이다.
이미 프로그래밍을 할 수 있고, 웹 통신을 할 수 있다면, 위 방법들을 통해 적어도, 낮은 수준의 코딩에서라도 GET Method를 구현할 수 있다고 생각한다.
RESTful API는 HTTP Methods를 이용하여 데이터를 조작할 수 있는 도구다. RESTful 하다는 것은 대표적으로 GET, POST, PUT(PATCH), DELETE, OPTIONS, HEAD를 이용하여 데이터를 조작하는 것인데, 이는 다음 글에서 얘기하도록 하고 오늘은 RESTful 하다는 것은 어떤 가이드 라인을 지켜야 하는지 얘기하려 한다. 물론 아직 나도 RESTful을 완전히 구현할 수 없기 때문에, 이 글을 읽는 독자께서 내가 설명하고자 하는 것에 의문이나 현실과 괴리감을 느낄 수 있다. 그럴 경우 알려주시면 감사하겠다.
우선, REpresentational State Transfer이라는 이름과 같이 '상태를 표현하는' 아키텍처가 RESTful API다. 상태를 표현하기 위해 많은 방법이 있겠지만, 그중 RESTful API는 HTTP 프로토콜을 이용한다. 즉, URI를 이용해 얻고자 하는 대상에 대한 상태를 획득할 수 있다. HTTP를 이용하기 때문에, 우리가 얻는 특징은 다음과 같다.
1. 캐싱 : HTTP자체의 Last-Modified 등 태그를 이용하여 캐싱을 할 수 있으며, 필요시 기능 구현을 위한 내용을 서버에 미리 정의해 놓을 수 있다. 2. 무상태성 : HTTP 프로토콜은 요청에 대한 응답을 통한 통신이기 때문에, REST API는 응답 전/후에 아무 상태를 갖지 않는다. 3. 계층형 구조 : HTTP 프로토콜 이외의 계층을 API 요청 처리를 위한 객체(혹은 동작) 안에 정의하여 보안, 유저인증, 암호화 등을 Flexible하게 추가할 수 있다. 클라이언트는 RESTful API 서버에 단지 '요청'을 보내고, 이 안의 동작을 알 필요가 없기 때문에 이런 설계가 가능하다.
1. 캐싱
캐싱은 간단하다. 우리가 흔히 알고있는 그 캐싱을 의미하며, 같은 URI에 대해 조회 요청이 발생했을 때, 일전에 가지고 있는 데이터로 응답하기 위한 기능이다. 서버 어딘가에 캐싱을 위한 객체를 만들어 놓고, lifetime, 새로운 생성 요청 등 특정 트리거가 발동되면 캐싱된 데이터를 무시하고, 새로운 조회를 한 뒤에 해당 결과를 캐싱하면 된다.
2. 무상태성
무상태성은 그냥 말 그대로 HTTP는 아무 상태를 갖지 않기 때문에 발생하는 특징이다.
3. 계층형구조
계층형 구조는 HTTP 요청이 클라이언트 <--> 서버간 발생하는 통신이고, 클라이언트는 서버가 어떻게 동작하는지 알 필요 없이 요청을 보내고, 서버는 내부의 동작을 통해 응답을 생성하여 보내면 된다. 따라서 서버는 내부에 계층을 추가할 수 있고, 이로 인해 계층형 구조(Layered Structure)라는 특징을 갖는다. 쉽게 말해 User Authenticate Layer, Cryptography Layer, Secure Layer 등 원하는 것을 서버에 구성해 놓고, 사용자는 단지 여기에 유저 토큰, 공개키, HTTPS 통신 등 알맞은 요청을 보내면 된다.
이와 별개로, HTTP를 이용하기 때문에 주의해야 할 특징들도 있다.
첫 째, URI에 목적을 명시해서는 안된다.
RESTful API는 보통 데이터의 관리를 위한 내용 제공이 대부분이고, 따라서 데이터 조회, 수정, 삭제 등 관련 내용을 수행함에 따라 직관적으로 알기 위해 다음과 같이 설계하는 경우가 있다.
즉 이처럼 uri 자체에 데이터 조작과 관련된 목적의 행위를 기술하지 않아야 한다. 데이터 조작과 관련된 행위는 모두 HTTP 6 Methods에 정의되어 있다. 즉, 위 요청은 다음과 같이 변환되어야 한다.
GET /user/name
둘 째, URI Segment를 활용하여 대상을 한정한다. 그리고 Query String을 활용해 기능을 할당해라.
Query String을 활용하여 RESTful API에 대한 접근을 하는 경우도 많지만, 만들때는 편하더라도 꽤 불편할 수 있다. 이 두번 째 내용은 내가 MkWeb에서 RESTful API를 설계하며 얻은 팁이다. Query String은 보통 URI 제일 마지막 세그먼트 이후에 붙는 녀석인데, 다음과 같이 생겼다.
GET /user?id=짧은머리%20개발자&age=~...
RESTful API에 대해 어느정도 이해한 사람은 위 구문이 Query String을 통해 대상을 한정한 구문이다. 하지만 우리가 데이터를 검색할 때는 많은 제약조건이나 요구사항에 마주할 수 있다. 예를 들어, 검색 내용에 대해 정렬시키거나, 모두 소문자 혹은 대문자로 바꾸거나, 한 페이지에 불러올 개수를 바꾸는 등. 우리가 딱딱한 RESTful API를 설계하게 되면, 이는 수정할 수 없게된다. 혹은 대상 한정자와 추가 기능에 대해 모두 Query String으로 해버리면, 사용할 때 꽤나 까다로울 수 있다. 따라서 다음과 같이 정의하는 것이 좋다.
GET /user/id/짧은머리 개발자/age/13?order=desc&lowercase&numOfRows=20
파란색은 대상 한정자,보라색은 추가 기능이다.
셋 째, 데이터 대상에 대한 내용이 아닌 이상 소문자를 사용하고, 확장자는 표시하지 마라.
소문자는 일관된 사용성을 위해 추천하는 바고, 확장자는 보안을 위해, 그리고 조금 더 유연한 자원 활용을 위해 표시하지 마라.
이러한 특징을 잘 지켜서 작성하면 RESTful API라 칭할 수 있다. 그렇다고, 캐싱을 안했다 해서 RESTful API가 아닌 것은 아니다. 특징들은 모두 '설계를 위한 가이드라인'이지, '설계를 위한 매뉴얼' 같은 것이 아니다. 그렇다 해서 딱 하나만 지키고 RESTful API라 하는 사람은 없을거라 믿는다.
어떤 서비스를 개발할 때 본래 필수적인 기능은 아니었지만, 이제는 필수적인 기능이 되어버린 API와 관련하여 글을 작성하려 한다. 이 중 굉장히 많이 쓰이고, 한번도 안 써본 사람은 있어도 한번만 쓰는 사람은 없는 RESTful API와 관련된 글을 작성할 것이다.
API, 도대체 뭐길래?
Application Programming Interface. 말 그대로 애플리케이션을 프로그래밍하기 위한 인터페이스다. 어떤 서비스에는 많은 시스템이 결합하게 되고, 각 시스템은 서로 다른 성격을 가진 녀석들이다. 예를 들어 웹 서비스를 개발한다 할 때, 간단하게는 서버와 클라이언트로 나눌 수 있고, 서버는 그 안에 데이터베이스, 파일 시스템, 웹 서버 ... 가 존재하며, 클라이언트도 모바일, 데스크탑, IoT등 여러 가지로 나눌 수 있다. 즉 어떤 서비스를 개발 하려면, 위와 같은 성격이 다른 녀석들을 모두 설계, 개발해야 하고, 결국에는 통합하여 하나의 서비스를 제공해야 한다. API는 이 때 사용할 수 있는 어떤 인터페이스다. Interface, 예전에 인터페이스와 관련된 내용을 작성했는데, 해당 글의 내용을 빌려 정의하자면 다음과 같이 말할 수 있다.
여러 사람이 함께 작업할 때, 틀이 되는 것 또는 그러한 가이드라인
RESTful 하다는건 뭐지?
API는 이제 알겠는데..
많은 사람들이 헷갈리는게 있는데, REST API는 없다. 다만, RESTful 한 API를 설계 하고, 이러한 것을 REST API라고 줄여서 부르기는 한다. 나 또한 REST API로 줄여서 부를 때가 많다. 내가 MkWeb의 RESTful API를 개발할 때 애를 먹었던 이유도 위와 같이, 무지에서 비롯한 사고의 불가능, 즉 설계를 할 수 있는 밑바탕이 없었기 때문에, 오랜 시간이 걸렸고, 시행착오를 많이 거쳤다. 이론을 바탕으로, 설계할 수 있어야 한다고 생각하는 나지만, RESTful 그 자체가 어떤 설명임에도 불구하고, 그래서 REST API는 어떻게 만드는건데?라는 생각으로 시간을 많이 소모했다.
RESTful 하다.
RESTful 하다는 것은 기본적으로 다음과 같은 의미를 갖는다고 나는 정의내렸다.
HTTP Methods를 사용하여 단말간 통신하면서 필요한 정보를 주고 받을 수 있는 Tool. 또는 그러한 방식
'서버'와 이를 이용하는 '엔드 포인트'의 통신이라 할 수 있지만, 사실 요즘 세상에 그것도 Blockchain이 크게 발전하고 있는 시대에 이르러 이러한 구시대적인 발상으로 정의하고 싶지 않았고, 따라서 '단말간 통신'이라고 나는 정의내렸다. 여기까지 아무런 질문없이 이해했다면, 그리고 단 한번도 RESTful API를 접해본 적이 없다면 한번 깊게 생각해보길 바란다.
애플워치7을 구매하면서 가장 고민했던게, 나이키를 살지 일반을 살지 엄청 고민했다. 나이키랑 일반모델의 차이는 나이키 전용 워치 페이스가 포함되어 있느냐의 차이 뿐이고, 고전적인 시계의 페이스를 선호하는 나로써는 딱히 안쓸거 같아서 일반 모델로 결정했다. 지금보니 나이키 모델 기본 워치 페이스가 좀 얄밉다.
색상은 실물을 보기 전에는 스타라이트를 사려 했지만, 내 손목에 갖다 댄 순간 미드나이트로 결정했다. 약간 스타라이트는,, 여자를 타겟으로 해서 나온 느낌..? 스타라이트 45mm는 너무 거대했고, 41mm는 그냥 딱 여자꺼였다.
와 상자 너무 예뻐.. 역시 애플은 제품을 개봉할 때 사람을 두근거리게 하는 포인트를 잘 알고있다. 패키징도 진짜 예쁘게 되어있고, 뜯는 맛도 있다.
아이폰13 프로로 사진 대충 찍었는데,, 화질 진짜 좋다.. 역시 인생은 장비빨..
상자를 다 까고 연결하고 있는데,, 영롱하다.
애플워치 SE의 경우 아이폰11 프로와 연동 시간이 꽤 오래 걸렸는데, 애플워치 7과 아이폰13 프로의 연동은 한 5분? 만에 끝난 것 같다.
엄마랑 IFC몰 간 시간이 점심이기도 했고, 밥먹자 하셔서 IFC몰 L3에 있는 제일제면소에서 점심을 먹었다. 엄마가 드신 음식은 엄마가 찍을 줄 알았는데 안찍으셨네..ㅋㅋㅋ사진이 없다..
내가 먹은건 매콤 닭갈비 덮밥인데, 맵다. 꽤 맵다. 오.. 매운거 좋아하시는 분들, 이건 꽤 맵다.
IFC몰 식사시간을 보면 대게 근무하시는 분들이 오시는 것 같은데, 이건 꽤 맵다.. 정수리에 땀 엄청 난다.. (내가 그랬다..)
음식은 전체적으로 짜거나, 싱겁지 않게 간이 잘 돼 있었다. 식당도 엄청 크다. (입구로부터 안으로 엄청 들어가서야 자리를 안내받았다.)
제일 신기했던건, 계산하러 갈 때 영수증을 지참하지 않았음에도 우리가 뭘 먹었는지 이미 알고 계시던데, 어떻게 아는거지...?
기존 투명 케이스는 하단이 노출되어 있었고, 해당 부분은 기스가 많이 생기기 때문에 꽤 신경쓰이는 부분이었다.
그래서 대안 제품을 찾고 있었는데, 아사모카페에서 화이트스톤사의 강화유리 EZ글라스와 SCOPE 케이스 체험단을 모집하고 있길래 신청했고, 운좋게 선정됐다!
먼저 강화유리를 부착하고, 케이스를 휴대폰에 씌울 예정이다.
9H강화유리, FullClear, Full Touch, 강력한 올레포빅 코팅 기스에 강한 EZ글라스
우선 강화유리 스펙은 다음과 같다.
1. 9H 화학처리 강화유리 - 9H 경도를 가져 일상 스크래치부터 강한 보호력을 갖는다. 2. Full Clear - 빛 투과율이 띄어나 디스플레이를 왜곡 없이 있는 그대로 보여준다. 3. Full Touch - 생폰과 같은 터치감! 4. 강력한 올레포빅 코팅 - 지문과 기름으로부터 강하며, 이물질이 잘 묻지 않는다.
구성품은 강화유리 본품 1매 부착을 도와줄 부착지그, 액정 클리너 1매, 먼지제거 스티커 1매, 극세사 1매로 이루어져 있다.
먼저 액정 클리너 1매를 이용하여 휴대폰 액정의 이물질을 제거하자. 이 때, 깨끗하게 닦는다고 액정 클리너로 엄청 문대게 되면 정전기로 인해 먼지가 액정에 많이 붙게되니 적당히 보이는것만 제거한다는 심정으로 닦아주면 된다.
이어서 극세사를 이용해 물기를 한번 훑어서 없앤다는 생각으로 닦아주자. 마찬가지로 세게 닦으면 먼지가 많이 붙게되니, 적당히 한-두번정도 닦아준다.
그리고 나면, 부착지그를 휴대폰에 씌우고, 먼지제거 스티커를 이용해 남아있는 먼지를 제거해주자. 먼지는 대충 제거하면 강화유리에 그대로 남는다. 하지만 마찬가지로, 스티커로 계속 먼지를 떼어내면 오히려 더 많이 붙게되니, 한번에 제대로 딱! 제거한다는 느낌으로 하자!
그리고 나서 강화유리 본체를 지그의 하단부터 맞춘 다음 잘 부착한다.
기포가 남아있을수 밖에 없는데, 해당 기포는 액정의 중앙부터 十자를 그리며 바깥으로 밀어내어 주면 된다.
이렇게 남은 기포는 하루-이틀 정도 지나면 자연스레 사라지니, 너무 걱정하지 않아도 된다. 이제 부착지그를 제거하면 끝 강화유리 부착은 모두 끝!
프리미엄 소재 단단한 PC, 말랑한 TPU의 조합
후면은 충격에 강한 PC소재로 되어있고, 측면은 케이스를 씌우거나 벗기고, 버튼을 누르는 등 실제로 사용자가 사용하는 부분이기에 말랑한 TPU로 되어있다.
EZ 글라스와 SCOPE 케이스의 조합은 꽤 볼만하다. 특히 EZ글라스의 겉은 검정색 선이 있는데, SCOPE 케이스의 테두리가 검정색으로 표현된것 처럼 아이덴티티마냥 어색하지않고 잘 어울린다.
강화유리
터치감은 기존에 쓰던 ESR의 제품보다 10%정도 더 좋은것 같다. 조금 더 쫀득한 느낌이다. 부착 난이도는 ESR과 같으니 패스.
화면 투과율은 차이를 잘 모르겠다. 근데 더 쫀득해서 기분이 좋음!
케이스
맥세이프가 가능하다고 되어있는데, 내가 갖고있는 오주주 3in1 맥세이프 충전기에는 붙지 않아서 사진을 찍지 못했다. 그렇다고 맥세이프가 포함된 케이스는 아니다.