개념
- REST 아키텍처 스타일의 제약 조건을 준수
- RESTful 웹 서비스와 상호 작용할 수 있도록 하는 애플리케이션 프로그래밍 인터페이스(API 또는 웹 API)
API(Application Programming Interface)란?
- 소비자에게 필요한 콘텐츠(호출)와 생산자에게 필요한 콘텐츠(응답)를 구성합니다.
- 예, 날씨 서비스용 API
- 사용자는 우편번호를 제공하고
- 생산자는 두 부분(첫 번째는 최고 기온, 두 번째는 최저 기온)으로 구성된 응답으로 답하도록 지정
- 예, 날씨 서비스용 API
- 목적
- 상호 작용하여 정보를 검색하거나 기능을 수행하고자 할 때 API는 사용자가 원하는 것을 시스템에 전달할 수 있게 지원하여 시스템이 이 요청을 이해하고 이행하도록 할 수 있습니다.
- 장점
- API는 조직이 보안, 제어, 인증을 유지 관리(누가 무엇에 액세스할 수 있는지 결정)하면서 리소스와 정보를 공유할 수 있는 방법이기도 합니다.
- 캐싱, 즉 리소스 검색 방법 또는 리소스의 출처에 대해 자세히 알 필요가 없다는 것입니다.
REST(Representational state transfer, RESTful, 레스트풀)
- REST는 프로토콜이나 표준이 아닌 아키텍처 제약 조건
- API를 통해 요청이 수행될 때 리소스 상태에 대한 표현을 요청자 또는 엔드포인트에 전송
- HTTP: JSON(Javascript Object Notation), HTML, XLT, Python, PHP 또는 일반 텍스트를 통해 몇 가지 형식으로 전송
- 헤더와 매개 변수는 요청의 메타데이터, 권한 부여, URI(Uniform Resource Identifier), 캐싱, 쿠키 등에 대한 중요한 식별자 정보를 포함
- RESTful API HTTP 요청의 HTTP 메서드도 중요
RESTful 조건
- 클라이언트, 서버 및 리소스로 구성, 요청이 HTTP를 통해 관리되는 클라이언트-서버 아키텍처
- 스테이트리스(stateless) 클라이언트-서버 커뮤니케이션: GET 요청 간에 클라이언트 정보가 저장되지 않으며, 각 요청이 분리되어 있고 서로 연결되어 있지 않음
- 클라이언트-서버 상호 작용을 간소화하는 캐시 가능 데이터
- 요청된 리소스가 식별 가능하며 클라이언트에 전송된 표현과 분리되어야 합니다.
- 수신한 표현을 통해 클라이언트가 리소스를 조작할 수 있어야 합니다
- 클라이언트에 반환되는 자기 기술적(self-descriptive) 메시지에 클라이언트가 정보를 어떻게 처리해야 할지 설명하는 정보가 충분히 포함되어야 합니다.
- 하이퍼텍스트/하이퍼미디어를 사용할 수 있어야 합니다. 즉, 클라이언트가 리소스에 액세스한 후 하이퍼링크를 사용해 현재 수행 가능한 기타 모든 작업을 찾을 수 있어야 합니다.
- 요청된 정보를 검색하는 데 관련된 서버(보안, 로드 밸런싱 등을 담당)의 각 유형을 클라이언트가 볼 수 없는 계층 구조로 체계화하는 계층화된 시스템.
- 코드 온디맨드(선택 사항): 요청을 받으면 서버에서 클라이언트로 실행 가능한 코드를 전송하여 클라이언트 기능을 확장할 수 있는 기능.
참고
https://www.redhat.com/ko/topics/api/what-is-a-rest-api
설계 규칙
- 1. URI는 동사보다는 명사를, 대문자보다는 소문자를 사용하여야 한다.
- 2. 마지막에 슬래시 (/)를 포함하지 않는다.
- 3. 언더바 대신 하이폰을 사용한다.
- 4. 파일확장자는 URI에 포함하지 않는다.
- 5. 행위를 포함하지 않는다.
참고
https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
RESTfull API 적용
아래와 같은 Consumer 엔티티 정보를 생성한다.
@Getter
@Entity
@Table(name = "CONSUMERS")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Consumer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CONSUMERS_ID")
private Long id; // pk값
@Column(name = "NICKNAME", unique = true)
private String nickname; // 닉네임
@Column(name = "PHONE_NUMBER", unique = true)
private String phoneNumber; // 휴대전화 번호
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "TICKET")
private Ticket ticket; // 예매 티켓
@CreationTimestamp
@Column(name = "CREATE_AT")
private LocalDateTime createAt; // 생성 시간
@UpdateTimestamp
@Column(name = "UPDATE_AT")
private LocalDateTime updateAt; // 수정 시간
}
ConsumerRepository를 생성한다.
@Transactional(readOnly = true)
public interface ConsumerRepository extends JpaRepository<Consumer, Long> {
boolean existsByNicknameOrPhoneNumber(String nickname, String phoneNumber);
}
다음으로 Link 를 생성해야 한다.
Link는 문자열로 하드 코딩하지 않고 WebMvcLinkBuilder 로 생성한다.
Link link = WebMvcLinkBuilder
.linkTo(methodOn(ConsumerController.class).consumerFind(consumerId))
.withSelfRel();
Controller 의 단건 조회 메서드
@GetMapping("/consumers/{id}")
public ResponseEntity<RestFullConsumerResponseDto> consumerFind(@PathVariable("id") final Long consumerId) {
ConsumerResponseDto consumerResponseDto = ConsumerResponseDto.of(consumerService.findConsumer(consumerId));
Link link = WebMvcLinkBuilder
.linkTo(methodOn(ConsumerController.class).consumerFind(consumerId))
.withSelfRel();
RestFullConsumerResponseDto dto = RestFullConsumerResponseDto.builder()
.consumer(consumerResponseDto)
.link(link)
.build();
return ResponseEntity.status(HttpStatus.OK).body(dto);
클라이언트의 응답 메시지를 살펴보면 RESTfull 하게 응답이 나오는 것을 확인해볼 수 있다.
{
"consumer": {
"nickname": "기영이",
"id": 1,
"phone": "01012341230",
"create_at": "2023-01-19T21:14:53.971178"
},
"link": {
"rel": "self",
"href": "<http://localhost:8080/consumers/1>"
}
}
.
'Spring' 카테고리의 다른 글
[Spring] EventPublisher 를 알아보자 (0) | 2022.09.22 |
---|---|
[스프링 웹 MVC 동작 원리] Dispatcher Servlet 동작 원리 (0) | 2022.03.28 |
[스프링 웹 MVC 동작 원리] Front Controller 가 무엇인가요? (0) | 2022.03.28 |
[스프링 웹 MVC 동작 원리] Servlet 환경에서 Spring Ioc Container 활용 (0) | 2022.03.28 |
[스프링 웹 MVC 동작 원리] ServletFilter 동작 원리 (0) | 2022.03.28 |
[스프링 웹 MVC 동작 원리] ServletListener 동작 원리 (0) | 2022.03.28 |
[스프링 웹 MVC 동작 원리] Servlet 동작 원리 (0) | 2022.03.28 |
[스프링 웹 MVC 동작 원리] DispatcherServlet (0) | 2022.01.28 |