소개 이음 이라는스타트업에서일하는, 올해로 4 년차인자바개발자

Similar documents
Web Service Computing

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

Week13

슬라이드 1

JUNIT 실습및발표

ibmdw_rest_v1.0.ppt

JAVA PROGRAMMING 실습 08.다형성

예제 2) Test.java class A intvar= 10; void method() class B extends A intvar= 20; 1"); void method() 2"); void method1() public class Test 3"); args) A

신림프로그래머_클린코드.key

JAVA PROGRAMMING 실습 09. 예외처리

Mobile Service > IAP > Android SDK [ ] IAP SDK TOAST SDK. IAP SDK. Android Studio IDE Android SDK Version (API Level 10). Name Reference V

(Microsoft PowerPoint - java1-lecture11.ppt [\310\243\310\257 \270\360\265\345])

작성자 : 김성박\(삼성 SDS 멀티캠퍼스 전임강사\)

C# Programming Guide - Types

Spring Boot/JDBC JdbcTemplate/CRUD 예제

PowerPoint Template

KYO_SCCD.PDF

I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r

어댑터뷰

Microsoft PowerPoint - CSharp-10-예외처리

PowerPoint Presentation

PowerPoint 프레젠테이션

<4D F736F F F696E74202D20C1A632C8B8C7D1B1B9BDBAC7C1B8B5BBE7BFEBC0DAB8F0C0D32D496E E D56432E BC8A3C8AF20B8F0B5E55D>

gnu-lee-oop-kor-lec06-3-chap7

2장 변수와 프로시저 작성하기

09-interface.key

rmi_박준용_final.PDF

PowerPoint Presentation

ThisJava ..

Spring Boot

게시판 스팸 실시간 차단 시스템

Cluster management software

Microsoft PowerPoint - 04-UDP Programming.ppt

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일

Microsoft Word - src.doc

DocsPin_Korean.pages


Microsoft PowerPoint - java1-lab5-ImageProcessorTestOOP.pptx

Intro to Servlet, EJB, JSP, WS

제8장 자바 GUI 프로그래밍 II

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

Microsoft PowerPoint - 11주차_Android_GoogleMap.ppt [호환 모드]

내장서버로사용. spring-boot-starter-data-jpa : Spring Data JPA 사용을위한설정 spring-boot-devtools : 개발자도구를제공, 이도구는응용프로그램개발모드에서유 용한데코드가변경된경우서버를자동으로다시시작하는일들을한다. spri

제11장 프로세스와 쓰레드

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

Design Issues

Network Programming

쉽게 풀어쓴 C 프로그래밍

14-Servlet

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

thesis

오버라이딩 (Overriding)

혼자서일을다하는 JSP. 이젠일을 Servlet 과나눠서한다. JSP와서블릿의표현적인차이 - JSP는 <html> 내에서자바를사용할수있는수단을제공한다. - 서블릿은자바내에서 <html> 을작성할수있는수단을제공한다. - JSP나서블릿으로만웹페이지를작성하면자바와다양한코드가

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

- 목차 - - ios 개발환경및유의사항. - 플랫폼 ios Project. - Native Controller와플랫폼화면연동. - 플랫폼 Web(js)-Native 간데이터공유. - 플랫폼확장 WN Interface 함수개발. - Network Manager clas

12-file.key

서현수

PowerPoint Presentation

Microsoft PowerPoint - web-part03-ch20-XMLHttpRequest기본.pptx

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

- JPA를사용하는경우의스프링설정파일에다음을기술한다. <bean id="entitymanagerfactory" class="org.springframework.orm.jpa.localentitymanagerfactorybean" p:persistenceunitname=

MVVM 패턴의 이해

Microsoft PowerPoint - web-part03-ch19-node.js기본.pptx

Windows Live Hotmail Custom Domains Korea

순서 OAuth 개요 OAuth 1.0 규격 OAuth 2.0 규격

Windows 8에서 BioStar 1 설치하기

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D D382E687770>

오핀 (OFIN) SDK Guide Fintech Mobile SDK Guide - Android V 1.0 OPPFLIB 1

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

교육자료

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap06-2pointer.ppt

슬라이드 1

Microsoft PowerPoint - Smart CRM v4.0_TM 소개_ pptx

Interstage5 SOAP서비스 설정 가이드

Microsoft PowerPoint - Supplement-03-TCP Programming.ppt [호환 모드]

Spring Data JPA Many To Many 양방향 관계 예제

C++ Programming

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras

쉽게 풀어쓴 C 프로그래밊

본 강의에 들어가기 전

No Slide Title

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

이도경, 최덕재 Dokyeong Lee, Deokjai Choi 1. 서론

* Factory class for query and DML clause creation * tiwe * */ public class JPAQueryFactory implements JPQLQueryFactory private f

파일로입출력하기II - 파일출력클래스중에는데이터를일정한형태로출력하는기능을가지고있다. - PrintWriter와 PrintStream을사용해서원하는형태로출력할수있다. - PrintStream은구버전으로가능하면 PrintWriter 클래스를사용한다. PrintWriter


Microsoft PowerPoint - 03-TCP Programming.ppt

MasoJava4_Dongbin.PDF

XSS Attack - Real-World XSS Attacks, Chaining XSS and Other Attacks, Payloads for XSS Attacks

mytalk

chap 5: Trees

오늘날의 기업들은 24시간 365일 멈추지 않고 돌아간다. 그리고 이러한 기업들을 위해서 업무와 관련 된 중요한 문서들은 언제 어디서라도 항상 접근하여 활용이 가능해야 한다. 끊임없이 변화하는 기업들 의 경쟁 속에서 기업내의 중요 문서의 효율적인 관리와 활용 방안은 이

PowerPoint Presentation

파워포인트 템플릿

Microsoft PowerPoint - Java7.pptx

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

Transcription:

RESTful API (including Mobile) with Spring 3.1 윤성준 (@exnis)

소개 이음 이라는스타트업에서일하는, 올해로 4 년차인자바개발자

들어가기앞서 RESTful 의 R 도모르고 API 의 A 도모르던한개발자가 RESTful API 를만들기위해고민하고삽질한과정공유함으로써, RESTful 이무엇인지, 이를스프링에서어떻게구현할수있는지간략하게나마알아볼수있는시간이되었으면..

목차 RESTful API with Spring 3.1 API Exception Handling API Security API Test

REST?

REST(Representational State Transfer)

REST(Representational State Transfer) 표현 (Representational) - REST 리소스는 XML, JSON, 심지어 HTML 을포함하여리소스사용자에게가장적합한, 사실상거의모든형식으로표현할수있다 상태 (State) - REST 와작업할경우리소스에대해취할수있는액션보다리소스의상태에대해더많은관심을둔다 전달 (Transfer) - REST 는한애플리케이션에서다른애플리케이션으로어떤표현형식으로리소스데이터전달을포함한다 - 스프링인액션제 3 판中 -

REST(Representational State Transfer) 표현 (Representational) - REST 리소스는 XML, JSO N, 심지어 HTML 을포함하여리소스사용자에게가장적합한, 사실상거의모든형식으로표현할수있다

REST(Representational State Transfer) 상태 (State) - REST 와작업할경우리소스에대해취할수있는액션보다리소스의상태에대해더많은관심을둔다

REST(Representational State Transfer) 전달 (Transfer) - REST 는한애플리케이션에서다른애플리케이션으로어떤표현형식으로리소스데이터전달을포함한다

REST(Representational State Transfer) 리소스지향적이고, 애플리케이션을표현하는객체와명사를강조하며, 가장적합한형식이무엇이든간에서버에서클라이언트로 ( 또는그반대로 ) 리소스의상태를전달함

RESTful?

REST is not a standard; it's a style. http://www.xfront.com/rest-web-services.html

API?

API!...OTL

RESTful API?

RESTful API! RESTless : https://api.dropbox.com/getaccountinfo?id=1 RESTful : https://api.dropbox.com/1/account/info [GET] RESTless : https://api.dropbox.com/deletefile?id=1 RESTful : https://api.dropbox.com/1/fileops/delete [POST]

RESTful API! 평범한 HTTP URL 을통해호출됨 URL 이계층적이라, 왼쪽에서오른쪽으로읽다보면광범위한개념에서정확한개념으로이동함 쿼리파라미터를이용해리소스를식별하는대신에전체기본 UR L 이리소스를식별함 URL 은리소스로무엇을수행할지가아니라리소스를식별할뿐. 따라서리소스를식별하는 URL 은 GET 하거나 PUT 하거나에상관없이모두동일함 리소스로무엇을할지는 HTTP 메소드가결정할문제임

RESTful API! http://localhost:8080/articles [GET] : 글목록을가져옴 http://localhost:8080/articles/123 [GET] : id가 123인글을가져옴 http://localhost:8080/articles/123 [PUT] : id가 123인글을작성 http://localhost:8080/articles/123 [DELETE] : id가 123인글을삭제 동일한 URL 인 /articles/123 으로요청을처리함

RESTful API! 메소드 설명 안전? (safety) GET 서버에서리소스를조회한다. 리소스는요청 URL 에의해식별된다. O 멱등적? (idemp otency) O POST 요청 URL 을리스닝하는프로세서에의해처리되도록서버에데이터를전송한다. X X PUT 요청 URL 에있는서버에리소스를둔다. X O DELET E 요청 URL 에의해식별되는서버의리소스를삭제한다. X O 안전 (safe)? : 메소드가리소스의상태를변경하지않는것 멱등적 (idempotent)? : 반복되는요청이첫번째요청이후에발생할수있는어떠한부작용도일으키지않는다. ( 상태를변경할수도변경하지않을수도있음 )

실제로는 GET, POST 만사용

PUT 을사용하지않은이유 클라이언트가 URI 구조를미리알아야함 : 그러기위해서는 id 를클라이언트에알려줘야하고, 쓸데없는정보가노출됨 http://localhost:8080/articles/123 [PUT] http://localhost:8080/articles/write [POST]

DELETE 을사용하지않은이유 리소스를삭제할일이없음

RESTful API! - Tip 동사대신명사를사용하도록권장 : getdogs (x) à dogs (O) 단수명사보다는복수명사 : /dog (X) à /dogs (O) 추상적인명사가아닌시나리오에맞는구체적인명사사용 : /photos 와같은추상적인명사가아닌 /profilephotos 와같이명확한목적을알수있는명사를사용 /resource/identifier/resource : /owners/5678/dogs (5678 번주인의 dogs) : Identifier 는변경되지않는값 /dogs ( 전체 dog), /dogs/1 (1 번 dog) 출력결과형식을지정 : /dogs ( 기본은 json 이며 /dogs.json 과동일함 ), /dogs.xml 은 xml 형식으로출력 특정범위의값을가져올때는파라미터사용 : /dogs?limit=25&offset=50 결과를받기원하는항목선택 : /dogs?fields=name,color,location

RESTful API with Spring 3.1?

스프링이 REST 를지원하는방법 컨트롤러는 REST 의네가지주요메소드인 GET, PUT, DELETE, POST 를포함하여모든 HTTP 메소드에대한요청을처리할수있음 @PathVariable 에너테이션은컨트롤러가파라미터화된 URL( 경로의일부분에변수입력이있는 URL) 에대한요청을처리할수있도록함 리소스는 XML, JSON, Atom 그리고 RSS 같은데이털모델랜더링을위한새로운뷰구현을포함하여스프링의뷰와뷰리졸버를이용해클라이언트에가장적합한형태로리소스의뒤에서데이터를표현할수있음 뷰기반의응답의경우, ContentNegotiatingViewResolver 는클라이언트가원하는컨텐츠타입을만족시키는몇가지뷰리졸버에서생성한최적의뷰를선택할수있음 컨트롤러핸들러메소드에 @ResponseBody 애너테이션을적용하여뷰처리를완전히무시하고, 몇가지메시지변환기중하나로변환된값을클라이언트에대한응답으로변환 마찬가지로새로운 @RequestBody 애너테이션은 HttpMethodConverter 구현체와함께인바운드 HTTP 데이터를컨트롤러의핸들러메소드에전달하는자바객체로변환할수있음 - 스프링인액션제 3 판中 -

@Controller @RequestMapping @PathVariable @RequestParam @ResponseBody 사실, 스프링 MVC 에서다쓰던것들..

@RequestMapping @RequestMapping(value = "/files", method = RequestMethod.GET) @ResponseBody public void getfile(@requestparam( id") Integer id) { File file = fileservice.getfile(id); } http://localhost:8080/files?id=1 @PathVariable @RequestMapping(value = "/files/{id}", method = RequestMethod.GET) @ResponseBody public void getfile(@pathvariable( id") Integer id) { File file = fileservice.getfile(id); } http://localhost:8080/files/1

예를하나 들어보겠습니다

아이디 ( 이메일 ) 과비밀번호를입력하고로그인버튼을누르면, http://api.i-um.com/authentication/login email : exnis@naver.com password : ########## POST 방식으로호출 { } JSON으로리턴 "status":"success", "result": {"accesstoken": 28as9dyhd923!3e2" }, "error": "NULL"

예 ) 로그인 - Annotation 사용 http://api.i-um.com/authentication/login email : exnis@naver.com password : ########## mobiletype : IPHONE / ANDROID POST 방식으로호출 @RequestMapping("/authentication") @Controller public class AuthenticationApiController { } @RequestMapping(value = "/login", method = RequestMethod.POST produces = "application/json") @ResponseBody public ApiResult login( @RequestParam("email") String email, @RequestParam("password") String password ) { }

예 ) 로그인 - Annotation 사용 http://api.i-um.com/authentication/login email : exnis@naver.com password : ########## mobiletype : IPHONE / ANDROID POST 방식으로호출 @RequestMapping("/api/authentication") @Controller public class AuthenticationApiController { } @RequestMapping(value = "/login", method = RequestMethod.POST, pro duces = "application/json") @ResponseBody public ApiResult login( @RequestParam("email") String email, @RequestParam("password") String password ) { }

예 ) 로그인 - Annotation 사용 { } "status": "SUCCESS", "result": { "accesstoken": 28as9dyhd923!3e2" }, "error": "NULL" JSON 으로리턴 @RequestMapping("/api/authentication") @Controller public class AuthenticationApiController { } @RequestMapping(value = "/login", method = RequestMethod.POST, pro duces = "application/json") @ResponseBody public ApiResult login( @RequestParam("email") String email, @RequestParam("password") String password ) { }

예 ) 로그인 JSON 으로리턴 JSON 으로결과값을리턴하기위해서는? 1. MappingJacksonHttpMessageConverter 사용 2. MappingJacksonJsonView (JSON 지원 View 이용 ) & ContentNegotiatingViewResolver 사용 (JSON 외 XML 등다른 format 의 view 제공하고싶을때 )

예 ) 로그인 JSON 으로리턴 MappingJacksonHttpMessageConverter? Controller 가리턴하는오브젝트 HttpMessageC onverter 클라이언트가원하는리소스 MappingJacksonHttpMessageConverter : JSON MarshallingHttpMessageConverter : XML RssChannelHttpMessageConverter : RSS...

예 ) 로그인 JSON 으로리턴 MappingJacksonHttpMessageConverter 를사용하려면? 1. Servlet-context.xml 에 bean 선언추가 <bean class="org.springframework.web.servlet.mvc.annotation.requestmappinghandleradapter"> <property name="messageconverters"> <list> <bean class="org.springframework.http.converter.json.mappingjacksonhttpmessageconverter"> <property name="supportedmediatypes"> <value>application/json;charset=utf-8</beans:value> </property> </bean> </list> </property> </bean> ResponseBody 를통해반환되는값에한글이있을경우깨지는현상을방지하기위해넣어줌 2. JSON 으로 return 하고자하는 Controller 에 @ResponseBody 를붙여줌 @RequestMapping(value = "/login", method = RequestMethod.POST) @ResponseBody public ApiResult login(

로그인 public class ApiResult { private SuccessFail status; : SuccessFail 은 SUCCESS / FAIL 의 enum type private Object result; : API 를호출한쪽에전달되어야할값 ( 값이없으면 NULL) private ExceptionReason error; : error 가발생하면 error 에대한정보 (code) 를넣어줌 private String msg; (error 가 NULL 이아닌경우에만보이도록함 ) : error 가발생했을때클라이언트가뿌려줘야할메시지 } { } JSON 으로변환 "status":"success", "result":{"accesstoken":"28as9dyhd923!3e2"}, "error":"null"

다른예를 들어보겠습니다

예 ) 배지 RequestMapping 전략 1) 배지목록가져오기 @RequestMapping(value = "/badges", method = RequestMethod.GET) @ResponseBody public ApiResult getbadges( ) { }

예 ) 배지 RequestMapping 전략 2) badgeid 에해당하는배지가져오기 @RequestMapping(value = "/badges/{badgeid}", method = RequestMethod.GET) @ResponseBody public ApiResult getbadge(@pathvariable Long badgeid) { }

예 ) 배지 RequestMapping 전략 3) badgeid 에해당하는배지의사진들가져오기 @RequestMapping(value = "/badges/{badgeid}/photos", method = RequestMethod.GET) @ResponseBody public ApiResult getbadgephotos(@pathvariable Long badgeid) { }

배지 4) badgeid 에해당하는배지의 {slotnum} 번째사진가져오기 @RequestMapping(value = "/badges/{badgeid}/photos/{slotnum}", method = RequestMetho d.get) @ResponseBody public ApiResult getbadgephoto( @PathVariable Long badgeid, @PathVariable( slotnum ) Integer slotnum) { }

배지 5) badgeid 에해당하는배지의 {slotnum} 번째사진업로드하기 @RequestMapping(value = "/badges/{badgeid}/photos/{slotnum}/upload", method = Reque stmethod.post) public ApiResult uploadbadgephoto( @PathVariable Long badgeid, @PathVariable( photoorder ) Integer photoorder) { }

API Exception Handling

예외처리 Service 에서 Business Logic 이실행되다가 Exception 이발생하면 Controller 에서 catch 해서에러코드와메시지를리턴해줌 { } "status":"fail", "result":"null", "error":"invalid_email_password" "message":" 이메일또는비밀번호가틀렸습니다 "

예외처리 Exception 을상속받아별도의 Exception Class 를만듦 Exception extends A Exception private AExceptionReason exceptionreason; public enum AExceptionReason { 이유 1, 이유 2, 이유 3, 이유 4, }; : 예외가발생한이유를 enum 형으로정의함

예외처리 도메인 or 서비스마다 Exception(class) 과 Exception Reason(enum) 이생김 AException (class) AExceptionReason (enum) BException (class) BExceptionReason (enum) CException (class) CExceptionReason (enum) DException (class) DExceptionReason (enum) EException (class) EExceptionReason (enum) Fexception (class) FExceptionReason (enum) GException (class) GExceptionReason (enum) HException (class) HExceptionReason (enum) IException (class) IExceptionReason (enum) JException (class) JExceptionReason (enum)...

예외처리 코드의중복이발생! try { } catch (Exception e) { ApiError apierror = null; if (e instanceof AException) { apiresult.seterror((((aexception)e).getaexceptionreason()); } else if(e instanceof BException) { apiresult.seterror((((bexception)e).getbexceptionreason()); } else if(e instanceof CException) { apiresult.seterror((((cexception)e).getcexceptionreason()); } else { apiresult.seterror(unknown_exception); } Exception 개수만큼조건문늘어남!! } apiresult.setmessage(e.getmessage()); return apiresult;

예외처리 : 개선후 Enum 은 extend 가안되어서, interface 만든후 implements 하도록처리! ExceptionReason (interface) implements AExceptionReason (enum) BExceptionReason (enum) CExceptionReason (enum)

예외처리 : 개선후 Exception (class) extends FrontModuleException (a bstract class) public abstract ExceptionReason getexceptionreason(); extends AException (class) private AExceptionReason aexceptionreason; BException (class) private BExceptionReason bexceptionreason; @Override public ExceptionReason getexceptionreason() { return aexceptionreason; } @Override public ExceptionReason getexceptionreason() { return bexceptionreason; }

예외처리 : 개선후 Exception 개수가많아도하나로처리! try { } catch (FrontModuleException e) { apiresult.seterror(e.getexceptionreason()); apiresult.setmessage(e.getmessage()); } return apiresult; But 여전히코드의중복이발생!

예외처리 : 다른개선방안 ExceptionResolver ResponseEntity<?> ContentNegotiatingView Resolver http://dev.anyframejava.org/docs/anyframe/plugin/springrest/1.0.2/reference/html/ch10.html

API Security

API Security 적당히 회사내부에서만사용되는 API (private) 클라이언트 ( 앱 ) 와통신하는 API ( 반만 public) 꼼꼼히 3rd Party 나개발자에게공개된 API (public) 아래에해당할수록어플리케이션레벨의보안에신경써야!

API Security ID(Identity) : 누가 API request 를요청했는지확인 인증 (Authentication) : 주체의신원을주체가주장하는신원과대비해검증하는과정 (A 가정말로 A 가맞는지확인 ) 허가 (Authorization) : 인증된사용자에게권한들을승인하는과정 (A 가어떤액션을하려고할때, 그액션을하도록허용되었는지확인 ) API 에서이 3 가지를모두요구하지는않는다!

API Security ID(Identity) 만요구 - Google Maps API : API key 만알면 API 사용가능

API Security ID(Identity), 인증 (Authentication) 요구 Twitter API : username / password 를입력해서인증해야함

API Security ID(Identity), 인증 (Authentication), 허가 (Authorization) 요구 Facebook API : email / password 입력한후, 특정 action 에대한허가를요구함

이렇게했습니다

API Security Oauth OpenID SAML HTTP authentication WS-Security Basic API Key

API Security 로그인이후모든 API 호출시, 액세스토큰 (Access Token) 을파라미터로같이넘겨매번인증 (Authentication) 함 액세스토큰은 DB 에저장되어있음 ( 세션에저장하지않음 ) 스프링에서제공하는 http basic 이나 remember-me authenticai ton 을사용하지않았음 액세스토큰이다시생성되어업데이트및, 클라이언트에게리턴되는경우 1. 로그아웃후, 다시로그인 2. 다른기기에설치되어있는앱으로로그인

API Security { } "status": "SUCCESS", "result": { "accesstoken": 28as9dyhd923!3e2" }, "error": "NULL" 로그인성공 ApiResult abc(@requestparam("accesstoken") String accesstoken, ) { accesstoken 을 authentication 하는로직 } ApiResult def(@requestparam("accesstoken") String accesstoken, ) { accesstoken 을 authentication 하는로직 } ApiResult xyz(@requestparam("accesstoken") String accesstoken, ) { accesstoken 을 authentication 하는로직 } 코드의중복이발생!

API Security AccessToken 을인증하는로직을 Interceptor 로분리해서 Controller 메소드가실행되기전호출되도록처리함 public class MobileAuthenticationInterceptor extends HandlerInterceptorAd apter { } @Override public boolean prehandle(httpservletrequest request, HttpServletResponse response, Object handler) throws Exception { accesstoken 을 authentication 하는로직 }

API Security 특정유저 ( 슈퍼유저 ) 만호출가능한메서드를만들고싶을때 메서드호출보호 (Spring Security) 보안인터셉터엘리먼트를통한메서드보호 포인트컷을활용한메서드보호 애너테이션을활용한메소드보호 - 스프링 3 레시피中 - 장점 : 호출보호하고자하는메서드위에애너테이션만붙이면된다. 단점 : 나중에어디에애너테이션을적용했는지잊어버려검색해봐야한다.

API Security @Secured("ADMIN_USER") <!-- 스프링에서제공 --> @RolesAllowed( ADMIN_USER ) <!-- JSR-250 --> @PreAuthorize( hasrole( ADMIN_USER ) ) <!-- 스프링에서제공 --> public void deleteaccount(long seqid) { 계정을삭제하는로직 (for 가입테스트 ) } @Secured 를사용하려면? <global-method-security secured-annotations= enabled /> @RolesAllowed 를사용하려면? <global-method-security jsr250-annotations= enabled /> @PreAuthorize 를사용하려면? <global-method-security pre-post-annotations= enabled />

API Security - 잊지말아야할것! 클라이언트에정보를딱필요한만큼만준다. 민감한정보는절대넘겨주지않는다. ( 예 : 유저의 seq_id, 주민번호등 )

API TEST

출처 : http://www.biologyreference.com/ar-bi/bacterial-genetics.html API(Analytical Profil e Index) TEST?

클라이언트 ( 앱 ) 개발자나기획자가쉽고편하게 API 를테스트하게하려면?

API TEST REST Client 이용 (Firefox, Chrome 확장플러그인설치 )? 장점 : 설치및사용이쉽다. 단점 : 테스트해야할 API 들이많은경우, 매번 HTTP URL 을입력하기번거롭다. 개발자에게만친숙한환경이다.

이렇게했습니다

API TEST 웹테스트페이지

API TEST http://swagger.wordnik.com/ http://twitter.github.com/bootstrap/

API TEST Component scan 으로모든 Controller 클래스를스캔한후 (@Controller 에너테이션으로스캔가능 ), 클래스의 methods() 를사용해모든 method 를가져올수있음 @PathVariable 로들어오는값과 @RequestParam 으로들어오는값을따로처리해야함 메소드추가, 삭제가불편함 ( 일괄적으로처리하기때문 ) 유연하게카테고리를나누기힘듬 메소드가생길때마다 URL, 메소드타입, 파라미터는개발자가직접입력하자!

API TEST ApiTestEnum ApiTestManager ApiTestController ApiTestView (swagger, bootstrap) public enum ApiTestEnum { // A. 로딩페이지 IntroGate("A. 로딩페이지 ", "/intro", "GET", "gate"), 카테고리 URL HTTP 메소드명메소드 // B. 로그인 Login("B. 로그인 ", "/authentication/login", "POST", "login"), FindPassword("B. 로그인 ", "/authentication/password/find", "POST", "findpassword"), // C. 가입 IsVaildEmail("C. 가입 ", "/authentication/email/check", "POST", "isvalidemail"), AuthorizeName("C. 가입 ", "/authentication/name", "POST", "authorizename"),... private String apicategory; private String apiurl; private String methodtype; private String name; }

References 1. http://apigee.com/about/api-best-practices/all/ebook 2. [Book] 웹개발자를위한웹을지탱하는기술 3. [Book] 스프링인액션제 3 판 4. [Book] 스프링 3 레시피 5. [Book] 스프링시큐리티 3

Thank you for Li stening!