들어가기 앞서, REST API 4단계에 대해 간략하게 이야기 하겠다.
(REST API :
자원 중심으로 HTTP 프로토콜과 매서드를 사용하는 RESTful한 API)
0단계 : HTTP 프로토콜 사용하기.
1단계 : 자원 중심으로 설계하기.
2단계 : CRUD에 맞게 HTTP 메소드 사용하기
• 회원 목록 /members -> GET
• 회원 등록 /members -> POST
• 회원 조회 /members/{id} -> GET
• 회원 수정 /members/{id} -> PATCH, PUT, POST
• 회원 삭제 /members/{id} -> DELETE
위의 예시와 같이,
1단계는 member, 즉 자원(member) 중심으로 API를 설계하고,
2단계는 해당 역할에 맞게 HTTP 메서드(POST, GET...)를 사용한다.
3단계 : HATEOAS 적용하기.
Hypermedia As The Engine Of Application State의 약자. 하이퍼미디어를 애플리케이션의 상태를 관리하기 위한 메커니즘으로 사용한다.
{
"email" : "ddd@na",
"password" : "1234",
}
{
"email" : "ddd@na",
"password" : "1234",
"links" : [
{
"rel" : "patch",
"href" : "http://localhost:8080/members/patch"
}
]
}
왜 추가적인 정보(링크)를 서버에서 보내는가?
클라이언트와의 결합도 감소
HATEOAS를 사용하지 않고 클라이언트가 직접 서버의 API를 통해 URL을 구성하면, 강한 결합 발생.
즉, URL이 변경되면 클라이언트도 함께 수정되어야 함.
즉, 유지보수의 어려움 초래 가능.
클라이언트 탐색성 개선
HATEOAS를 사용하면, 클라이언트가 응답을 통해 제공된 링크를 따라 다른 리소스로 이동 가능.
API 사용의 편의성을 높일 수 있음.
서버의 자기설명적 API
HATEOAS를 사용하면 주고 받는 API 자체에 API가 포함되므로,
API의 문서화나 사전 지식 없이도 더 편하게 사용 가능.
의존성 추가 (gradle)
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
컨트롤러 코드
@GetMapping("/members")
public EntityModel<Member> retrieveUsers(){
Member member = memberService.findOne(id);
// EntityModel 클래스는
// RepresentationModel 클래스를 상속하고,
// RepresentationModel 클래스는 Link 객체를 담고 (로컬호스트:8080)
// EntityModel 클래스는 해당 링크를 가진 자원 객체를 담는다. (patch)
EntityModel<Member> model = new EntityModel<>(Member);
//linkTo, methodOn 정적 매서드를 사용하여 자동으로 링크를 생성한다.
//Resource와 Link를 함께 내려줌
//methodOn(this.getClass()) 까지가 링크 객체 담고,
//withRel이 자원 객체 담음
model.add(linkTo(methodOn(this.getClass()).withRel("patch"));
return model;
}
//여기까지를 구현한게 위의 HAL_JSON_VALUE
CORS는 Cross-Origin Resource Sharing 의 줄임말로,
교차 출처 리소스 공유를 의미하며,
교차 출처는 ‘다른 출처’라고 생각하면 이해하기 쉽다.
즉, 다른 출처 간의 자원을 공유하는 정책이라고 생각하면 된다.
반대되는 개념은 SOP가 있다.
Same-origin policy,
프로토콜, 도메인, 포트가 모두 같을 시 접근을 허용해주는 메커니즘이라고 볼 수 있다.
SOP가 원칙이고 CORS가 예외이다.
CORS를 통해 클라이언트는 다른 도메인에 있는 리소스를 자유롭게 사용.
소셜 미디어 API를 사용하여 사용자 인증, 데이터 가져오기 등을 처리와 같이 확장에 능함.
다양한 도메인에 있는 서비스 및 리소스를 웹 애플리케이션에서 통합하여 사용하는 것과 같이 다양한 웹 어플리케이션의 통합이 가능해짐.
@RestController
public class MyController {
@CrossOrigin(origins = "http://example.com")
@GetMapping("/api/resource")
public ResponseEntity<String> getResource() {
// 리소스 반환
}
}
위의 예제에서 @CrossOrigin(origins = "http://example.com") 어노테이션은 http://example.com 출처에서의 요청을 허용한다는 의미.
클래스 단위나, 매서드 단위로 애너테이션을 작성해서 더 자세하게 설정해줄 수 있음.
또는 Spring의 설정 파일인 application.properties 또는 application.yml에 다음과 같이 CORS 구성을 추가할 수 있음.
(properties의 예시)
spring.webmvc.cors.allowed-origins=http://example.com
spring.webmvc.cors.allowed-methods=GET,POST