자료 작성간 참고한, 읽어보면 좋은 글
( 표현적인 API )
1) 자원에 대한 행위는 HTTP Method로 표현
HTTP Method 중 대표적인 4가지 ( POST - 생성, GET - 조회, PUT - 수정, DELETE - 삭제) 를 사용한다.
2) URI는 정보의 자원을 표현
GET /members/delete/1 (x) ( 'delete' 라는 행위에 대한 표현이 들어간 URI )
DELETE /members/1 (o)
GET /members/show/1 (x)
GET /members/1 (o)
GET /members/insert/2 (x)
POST /members/2 (o)
3) URI는 자원을 표현하는 Colllection과 Document 로 구성
http:// restapi.example.com/sports/soccer/players/13
* sports , players 라는 Collection. (복수형 사용됨)
* Collection 안에, soccer, 13 이라는 Document
1) 슬래시 구분자(/)는 계층 관계를 나타내는 데 사용
http://restapi.example.com/houses/apartments ( 집 -> 아파트 )
http://restapi.example.com/animals/mammals/whales ( 동물 -> 포유류 -> 고래 )
2) URI 마지막 문자로 슬래시(/)를 포함하지 않는다.
http://restapi.example.com/houses/apartments/ (X)
http://restapi.example.com/houses/apartments (0)
3) 가독성을 위해서,
https://www.destiny.com/books/my-service
잘 설계된 REST API는 URI만 잘 설계된 것이 아닌 그 리소스에 대한 응답을 잘 내어주는 것까지 포함되어야 함.
등등, 성공/실패 여부에 맞는 적절한 Response status code 및 메세지를 응답!
// 요청
> GET /v1/search/movie.xml?query=%EC%A3%BC%EC%8B%9D&display=10&start=1&genre=1 HTTP/1.1
> Host: openapi.naver.com
> User-Agent: curl/7.49.1
> Accept: */*
> X-Naver-Client-Id: {애플리케이션 등록 시 발급받은 client id 값}
> X-Naver-Client-Secret: {애플리케이션 등록 시 발급받은 client secret 값}
// 응답 ( XML )
< HTTP/1.1 200 OK
< Server: nginx
< Date: Wed, 28 Sep 2016 07:40:17 GMT
< Content-Type: text/xml;charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Keep-Alive: timeout=5
< Vary: Accept-Encoding
< X-Powered-By: Naver
< Cache-Control: no-cache, no-store, must-revalidate
< Pragma: no-cache
<
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Naver Open API - movie ::'주식'</title>
<link>http://search.naver.com</link>
<description>Naver Search Result</description>
<lastBuildDate>Wed, 28 Sep 2016 16:40:17 +0900</lastBuildDate>
<total>2</total>
<start>1</start>
<display>2</display>
<item>
<title>주마등<b>주식</b>회사</title>
<link>http://openapi.naver.com/l?AAADWLQQvCIBzFP83f48h0zh08uK1B0S2IOm7mUEIts0F9+vQQPN77vQfv+dbxI2DXgyTQ9QV4B+2ATNSLMCk9gEjYjlkurFZXflp1rFRw/yXnbEspNk8vqypvPJBRhZsGMrSMY4ySwLSpN5RT3NSYIScO5nxhdzc18cjq0958w8LneKUy8fz6AdRxjD6YAAAA</link><image>http://imgmovie.naver.com/mdi/mit110/0968/96811_P01_142155.jpg</image>
<subtitle>走馬&amp;#28783;株式&amp;#20250;社</subtitle>
<pubDate>2012</pubDate>
<director>미키 코이치로|</director>
<actor>카시이 유우|쿠보타 마사타카|카지와라 히카리|치요 쇼타|요코야마 메구미|카시와바라 슈지|</actor>
<userRating>4.50</userRating>
</item>
...
</channel>
</rss>
GET/POST https://nid.naver.com/oauth2.0/authorize
- 네이버 로그인 인증을 요청합니다.
GET https://openapi.naver.com/v1/search/news
- JSON, XML응답 : 네이버 검색의 뉴스 검색 결과를 반환합니다.
POST [https://openapi.naver.com/v1/papago/n2mt](https://openapi.naver.com/v1/papago/n2mt)
- JSON응답 : 인공 신경망 기반의 기계 번역 결과(영어, 중국어(간체))를 반환합니다.
/v1/papago/n2mt API의 요청 예시
-H : 헤더
-d : 파라미터
curl "https://openapi.naver.com/v1/papago/n2mt" \
-H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
-H "X-Naver-Client-Id: {애플리케이션 등록 시 발급받은 클라이언트 아이디 값}" \
-H "X-Naver-Client-Secret: {애플리케이션 등록 시 발급받은 클라이언트 시크릿 값}" \
-d "source=ko&target=en&text=만나서 반갑습니다." -v
비로그인 방식 오픈 API 호출 예 (JAVA) https://github.com/naver/naver-openapi-guide/blob/draft/sample/java/APIExamTranslateNMT.java
주소 검색하기 예시
// 요청
curl -v -X GET "https://dapi.kakao.com/v2/local/search/address.json" \
-H "Authorization: KakaoAK ${REST_API_KEY}" \
--data-urlencode "query=전북 삼성동 100"
// 응답
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"meta": {
"total_count": 4,
"pageable_count": 4,
"is_end": true
},
"documents": [
{
"address_name": "전북 익산시 부송동 100",
"y": "35.97664845766847",
"x": "126.99597295767953",
"address_type": "REGION_ADDR",
"address": {
"address_name": "전북 익산시 부송동 100",
"region_1depth_name": "전북",
"region_2depth_name": "익산시",
"region_3depth_name": "부송동",
"region_3depth_h_name": "삼성동",
"h_code": "4514069000",
"b_code": "4514013400",
"mountain_yn": "N",
"main_address_no": "100",
"sub_address_no": "",
"x": "126.99597295767953",
"y": "35.97664845766847"
},
"road_address": {
"address_name": "전북 익산시 망산길 11-17",
"region_1depth_name": "전북",
"region_2depth_name": "익산시",
"region_3depth_name": "부송동",
"road_name": "망산길",
"underground_yn": "N",
"main_building_no": "11",
"sub_building_no": "17",
"building_name": "",
"zone_no": "54547",
"y": "35.976749396987046",
"x": "126.99599512792346"
}
},
...
]
}
// ECM - APIController 의 주요 메서드 일부
createDummySession[-ByUserCode] (HttpServletRequest, String) : boolean
logout(HttpServletRequest, HttpServletResponse) : void
getServerStatus(HttpServletRequest, HttpServletResponse) : ModelAndView
getRootOID(HttpServletRequest, HttpServletResponse) : ModelAndView
getFolderList(HttpServletRequest, HttpServletResponse) : ModelAndView
getDocumentList(HttpServletRequest, HttpServletResponse) : ModelAndView
downloadFile(HttpServletRequest, HttpServletResponse) : ModelAndView
createDownloadFileUrl(HttpServletRequest, HttpServletResponse) : ModelAndView
uploadFile(HttpServletRequest, HttpServletResponse) : ModelAndView
💡 결론
현대의 HTTP를 사용하는 API는 대부분 RESTful하다고 봐도 무방할 정도로, 사실상 HTTP의 표준처럼 사용되고 있습니다.
모든 상황과 애플리케이션에서 완벽한 아키텍처라는 뜻이 아니며 반드시 완전하게 설계 규칙을 준수해야만 하는 것이 아닙니다. (HATEOAS 구현 등)
위와 같은 설계 규칙을 준수하는 것은 내가 이해하고 다른 사람이 이해하는데 효율적이기 때문에 융통성을 갖고, 도구로써 적절히 잘 사용하는것이 중요할 듯 합니다.
좋은포스팅 감사합니다 :)