rest api 과거 글 그냥 참고용

반응형

 

https://developers.google.com/gmail/api/v1/reference/



결론은 요놈들을 본받자.
https://developers.google.com/gmail/api/v1/reference/
https://developers.google.com/ad-exchange/buyer-rest/v1.3/
https://developers.google.com/ad-exchange/seller-rest/reference/v2.0/?hl=ko

페이팔
https://developer.paypal.com/docs/api/

페이스북
https://developers.facebook.com/docs/graph-api/common-scenarios

드롭박스
https://www.dropbox.com/developers-v1/core/docs

카카오톡
https://developers.kakao.com/docs/restapi

구글
https://developers.google.com/gmail/api/v1/reference/
https://developers.google.com/ad-exchange/seller-rest/reference/v2.0/?hl=ko

트위터
https://dev.twitter.com/rest/public

아마존
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUT.html

링크드인
https://developer.linkedin.com/docs/signin-with-linkedin

구글이나 페이팔 쪽의 api 설계가 잘 되어 있는 듯 하다. 아마존은 아예 서버 자체를 제공하는 서비스를 하기 때문에 좀 특이한 듯 하고. 페이스북은 아예 id 값 자체로 분류하면서 nodes, edge, fields 라는 개념으로 구성한 듯 하다. 드롭박스의 경우 완벽한 rest 형식은 아닌 듯 하다.

하지만 rest 가 모든 로직을 표현할 수 있을까에 대한 의문이 든다.
users/:username
users/:username/friends
이런 컬렉션, 도큐먼트, 스토어 개념으로 리소스 중심으로만 되어 있다면 CRUD 만으로도 표현될 수 있다.

드롭박스의 경우 files, files_put 과 같이 분류한 것을 보면 좀 특이한데 완벽한 rest 는 아닌 듯 하다. /thumbnails 라는 api 가 있는데 이것의 경우 원하는 사이즈의 썸네일을 조건에 따라 얻어오는 행위를 할 수 있다. 이것 또한 CRUD 로 모두 표현은 가능한 듯 싶다. fileops/copy, fileops/create_folder, fileops/delete, fileops/move, fileops/permanently_delete 같은 것이 있는데 이렇게 동작의 경우를 rest 로 표현할 수 있을까?

v1/files - get
v1/files - post
v1/files/:id - put
v1/files/:id - delete
v1/files/:id

copy 하는 행위를 위해서는 대상에 v1/files - post 하고 v1/files/:id - delete 하는 식이 된다.
하지만 구글 측의 api 설계를 보면 rest 로도 충분히 가능하다. 약간의 변형된 rest 라고도 볼 수 있지만 동작도 표현이 가능하다. 원래 뷰 측의 url 설계에 있어서는 new, edit 같이 생성이나 수정 화면을 보여주는 url 이 users/:id/edit 와 같이 설계된다. rest 는 기본 CRUD 동작에 대해서는 request 의 method 로 구분 짓지만 좀 더 복잡한 동작에 대해서도 추가를 할 수 있다.

POST
https://www.googleapis.com/upload/gmail/v1/users/userId/drafts/send
and
POST /userId/drafts/send

이것과 같이 post 로 하여 맨 뒤에 동작을 붙여주면 copy 같은 행위를 하나로 묶어서 처리할 수 있다.

따라서 아마 드롭박스가 rest 를 좀 더 엄격하게 준수한다면
files/copy
files/create_folder
이런 식으로 되었어야 했을 것이다.
기본 CRUD 동작은 files 와 files/:id 로 되면서...

하지만 이런 특별한 목적을 위한 동작이 많은 경우 CRUD 동작을 중심으로 한 rest api 가 오히려 설계의 흐름을 방해할 수도 있지 않을까..

카카오톡의 api 설계를 보면 rest api 라고 칭하기는 하지만 rest 를 엄격하게 준수하지 않고 동작 중심으로 임의로 만들어 설계하였다.

구글의 경우 엄격하게 rest 의 룰을 따르고 있다. rest 가 완전히 정해진 규약 같은 것은 없지만 대략적인 설계 가이드 룰이 있다. 구글은 이를 준수하고 있다. 다른 사이트들의 경우 많이들 변형해서 사용하는 듯 하다. 페이팔 또한 이를 준수하고 있다.

rest 규약을 최대한 준수하면서 api 설계를 하다 보면 실제 상황에서는 빨리 진행되어야 하는 개발 상황에서 막 갖다 붙이기도 힘들고 또한 좀 복잡한 논리가 들어가면 난해해 지기도 할 것이다. 하지만 rest 룰을 최대한 따르면서 설계를 한다면 잘 정돈된 api 를 볼 수 있을 듯 하다.

users/:id 와 같은 것이 있지만 실제로는 로그인 한 자신의 정보를 보는 프로필의 페이지를 보는 경우를 생각해 보자. 옛날 방식의 웹에서는 /user/profile 이라는 뷰를 요청하면 서버 내부에서 로그인한 사용자의 정보를 바탕으로 /user/profile 에 해당하는 뷰를 파싱하여 내려보내었다. 하지만 웹앱 형식으로 완전히 서버와 클라이언트가 분리된 방식에서는 로그인한 자신의 id 를 알고 있고 요청 또한 이런 범용적인 rest api 서버에 users/:id 로 요청을 한다. 물론 이 요청에 대해 그 정보를 받을 수 있는가에 대한 권한은 서버 측에서 알아서 응답해줄 것이다. 자신이 로그인 되어 있다면 당연히 권한이 있을 것이고 프로필 페이지를 보여주는 것에 문제가 없다.

즉 rest api 는 범용적인 것이다. 자기의 서버에서 자기가 내려준 클라이언트의 동작 방식에만 국한된 것이 아니라 다른 서비스도 그것을 끌어다 쓸 수 있도록 또한 자신의 서비스에 국한되었더라도 이렇게 서버와 클라이언트가 완전히 독립적으로 프로그램 되는 것이 차후 유지 보수 측면에서도 좋을 것이다.

카카오나 드롭박스 같은 형식의 변형된 rest api 가 편할 수도 있겠지만 정석적인 rest 룰을 따르는 것이 더 좋을 거 같다.

user/me
user/ids
user/login
user/signup
user/unlink
api/story/isstoryuser
api/story/profile
/api/story/post/note
/api/story/upload/multi
/api/story/post/photo
/api/story/linkinfo
/api/story/post/link
/api/story/mystory
/api/story/mystories
/api/talk/profile

https://developers.kakao.com/docs/restapi#간편한-참조-rest-api
https://developers.kakao.com/docs/restapi#간편한-참조-응답-코드

카카오는 복수형을 사용하지 않는다. 나도 복수형을 좋아하지 않지만 일단 룰이 그러니 따라야겠다. 가령 person 은 people 이 되고 story 는 stories 가 되고 love 는 loves 가 되니... news 의 경우는? quiz 는 quizzes.. 추상명사는 복수가 없음에도 s 를 붙여야 하는가하며... 복수형이랑 단수형이 같은 경우 하며... 어쨌든 찝찝하지만 복수를 사용하는게 맞아보이긴 하다.

story/post/photo 이런식으로 표현했지만
엄격한 rest 방식 대로 라면
stories/
posts/:id/photoes 나
photoes 단독이거나...

그런데 story 의 post 의 photo 를 표현하기 위해서는...
그건 이미 story 의 post 의 photo 라는 자원이다. 범용적인 photo 가 아니다.
따라서 애초에 리소스 명 자체를 story_post_photo 라고 지어야 한다.
만약 photo 가 따로 범용적이라면 충분히
photoes 만으로도 접근 가능해야 하고
stories/:id/posts/:id/photoes 로도 접근 가능해야 하며
posts/:id/photoes 로도 접근 가능해야 한다.
물론 이런 복잡한 구조의 api 까지 만들 필요가 있을 경우에만...

story/mystory 같은 경우도 mystory 라는 api 를 두는 것 보다
클라이언트 측에서 자신의 아이디 값을 바탕으로 또는 스토리의 아이디 값을 바탕으로
stories/:id 로 던져주고 그것을 얻을 권한은 서버 측에서 알아서 판단하여 정보를 내려주는 것이 좋다.

이런 엄격한 rest 규칙을 적용하지 않은 사이트의 경우는 아마도 과거 서버에서 뷰 단을 파싱해서 보여주는 방식과 완전히 독립된 api 노출과의 혼란에서 야기되는 듯 하다.

솔직히 골 아프지 않게 미래를 생각하지 않고 그냥 막 만들면 그냥 쭉.... 자기 맘대로 대충 이름 지어서 /xxxx 형식으로 언더바나 카멜케이스로 구분지은 이름으로 루트에 하나만 두고 쭉 써내려 가면 정말 편하다... 이건 내가 해봐서 안다.. 그런데 그럴거면 그냥 영어 단어나 하나 더 외우는게 미래를 위해 더 건설적이지 않을까 생각한다. 헛된 곳에 노동력과 돈을 낭비하지 말고...

p.s. 언더바 ( _ ) 는 도메인에 있을 때만 문제가 된다. 쿼리 스트링에는 괜찮다. 서브도메인까지 모두 포함이다... 루비나 파이썬이 이런 rest api 명명법에 snake_case 방식을 사용하고 자바나 씨샾, 자바스크립트가 camelCase 를 사용한다. snake_case 를 추천을 많이들 한다. 페이팔은 바(-) 를 사용하고, 페북은 언더바, 드롭박스도 언더바 등등..
사실 디비 모델링에 있어서도 이것이 문제시 되는데 mysql 사용시에는 보통 나는 언더바 구분자를 사용하는 식이었다.. 디비 테이블 명 또한 복수를 안 쓰는 방식으로..
일단 난 구글을 따르기로 한다. 구글은 아예 구분자가 없다. uri (Uniform Resource Identifier)의 host 와 port 는 대소문자를 구분하지 않지만 그 이하는 구분한다. rfc3986.
따라서 /performanceReport 와 /performancereport 는 다른 uri 인데 구글은 후자를 사용한다. uri 는 모두 소문자인 것을 추천. 언더바도 사용하지 않도록 하는 방식을 사용할 것이다. 컨트롤러를 카멜케이스로 명명하더라도 toLowercase 하면 그대로 동일해지니깐 참 좋을 듯 하다.

도메인에 언더바가 있을 시 대체로 이런 문제들이 있다.

1. 익스에서 쿠키 생성이 안된다.
익스만 쿠키 생성이 안된다.
처음에는 익스의 쿠키 사용안함으로 되어있는 옵션를 확인 해 봤지만, 안된다.
익스 버젼 문제인가 했지만, 다른 버젼에서도 안됬다.
크롬,사파리,파이어폭스 심지어 안드로이드 기본 브라우져에서도
되는 쿠키 생성이 익스에서만 안된다.
처음 이런 현상을 접했을 때, 뭐 이런 경우가 다 있나 했는 데, 나중에 알고 보니 도메인 언더바
문제였다.
쿠키 생성은 물론 세션 생성도 안된다. 이경우는 도메인 변경후 테스트를 안해 봤지만, 확실할 것이다.

2. url창에서 해당 도메인으로 바로 들어가기가 안된다.
몇몇 브라우져에서는 언더바가 들어가 있는 도메인은 자동으로 http를 붙여서
해당 도메인으로 넘겨 주지 않고, 검색을 해 버린다.
그래서 http:// 를 붙여주고 나서야 해당 도메인으로 연결된다.

3. 안드로이드에서 .apk 파일 다운로드가 안된다.

처음에는 검색해서 나온 mime 타입 적어주는 걸로 해결하려고 했지만 안됬다.
일반 pc 브라우져에서는 해당 경로만 적어주면 모두 apk 파일이 다운된다.
안드로이드 기본 브라우저 나 크롬에서 해당경로를 적어 넣으면 파일 다운로드 실패가 뜬다.
(아이폰 사파리에서는 된다…필요는 없지만..)
이 역시 도메인 언더바 문제였다.

 

반응형

댓글

Designed by JB FACTORY