'우이삭' 프로젝트를 진행하며 팀원들과 함께 아래의 영상을 시청하였다.
그 결과, HAL_JSON_VALUE라는것을 적용해보았다.
그 외적으로도 아래의 영상을 보며 느낀것이 많았기에 적어본다.
영상에 대한 설명을 하자면
1991년 '팀 버너스리' 선생님께서 WEB을 만드셨다.
고민 : 인터넷으로 정보 공유할때, 어떻게 할 것인가
해답 : 정보들을 하이퍼텍스트로 연결한다.
'로이 필딩' 선생님은 HTTP의 기능을 더하고, 수정해야했음. 하지만 이미 WEB상에는 HTTP가 많이 사용되고 있었음. 따라서 호환성의 문제가 있음.
어떻게 하면 기본의 호환성을 유지하며 HTTP를 발전시킬 수 있을까? -> HTTP Object Model (=REST)
REST API: REST 아키텍쳐 스타일을 따르는 API
REST: 분산 하이퍼미디어 시스템(예:웹)을 위한 아키텍처 스타일
아키텍처 스타일: 제약조건의 집합
=> 즉, 제약조건들을 다 따르는 스타일을 REST API라고 한다.
그렇다면, REST를 구성하는 스타일에는 무엇이 있는가
나머지는 대부분 잘 지켜지고있다. 하지만 Uniform Interface가 잘 지켜지지 않는다.
Uniform Interface의 제약조건에는 무엇이 있는가
그렇다면 왜 Uniform Interface를 지켜야할까. -> 독립적인 진화
독립적인 진화는 무엇인가

웹은 REST를 굉장히 잘 지키고 있다. 그 결과 위처럼 동작할 수 있다.
몇몇 모바일 앱은 변경사항이 있으면 업데이트를 해야만 앱을 실행할 수 있다. -> REST를 잘 지키지 못했다.

왜 이정도로 긴 시간이 걸리는가 -> 하위 호환성을 깨뜨리면 안되기 때문.


시스템 전체를 통제할 수 있다: 내가 클라이언트와 서버를 모두 통제할 수 있다.
진화에 관심이 없다: 시스템을 수정할때마다 하위호환성이 되지 않고 업데이트를 계속 해야함.


큰 차이는 웹은 사람이 보고, API는 기계가 본다.
HTML은 Self-descriptive와 HATEOAS를 만족한다. 하지만 JSON은 만족하지 않는다.
Self-desciptive를 만족하면 왜 REST한가: 서버나 클라이언트가 변경되더라도 오고 가는 메시지는 self-descriptive하므로 언제나 해석이 가능하다.
HATEOAS를 만족하면 왜 REST한가: 해당 페이지에서 다음 페이지로 이동하는 링크를 마음대로 서버에서 변경해도 된다. 클라이언트측은 해당 URI만 참고하면 되기 때문.
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/v1/members", produces = MediaTypes.HAL_JSON_VALUE)
public class MemberController {
private final MemberService memberService;
@SneakyThrows
@GetMapping
public ResponseEntity<ApiResponse<MemberProfileGetResponse>> getMemberProfile(@LoginUser SessionUser sessionUser) {
return ApiResponse.ok(memberService.findMemberProfile(sessionUser.memberId()),
linkTo(methodOn(MemberController.class).getMemberProfile(sessionUser)).withSelfRel(),
linkTo(MemberController.class.getMethod("editMemberProfile", List.class, MemberProfileEditRequest.class, SessionUser.class)).withRel("edit member profile")
);
}
}
MemberController중 조회 API이다. MediaType을 HAL_JSON_VALUE로 설정했고, link를 설정해주었다.
{
"code": 200,
"body": {
"imageUrl": "http://k.kakaocdn.net/dn/utgdR/btsHicKT45I/ELHXKXPUTvfKZr2qaV2SZ0/img_640x640.jpg",
"nickname": "김재웅",
"birthday": null,
"mbti": null,
"calendarColor": null
},
"links": [
{
"rel": "self",
"href": "http://localhost:8080/v1/members"
},
{
"rel": "edit member profile",
"href": "http://localhost:8080/v1/members"
}
]
}
위처럼 현재 회원조회 페이지의 link와 회원수정 페이지의 link를 확인할 수 있다.