기본 CRUD 기능의 HTTP API를 빠르게 만드는 방법이 없을까?
Spring Data Rest 프레임워크를 알게 되었다. 일반적으로 사용하는 HTTP API가 아닌 깐깐한 Restful API를 빠르게 만들 수 있는 도구이다.
나의 결론
Restful 원칙을 지키고 간단한 기능의 API를 만드는데는 좋다.
하지만, 다양한 View의 요구사항을 만족시키는 HTTP API를 만드는데는 Spring MVC를 사용하는 것이 빠르다.
준비
사용할 패키지들을 추가한다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
클래스는 Entity와 Repository만 만들어주면 API가 자동 생성된다.
@Entity
@Getter
public class Comment {
@Id
@GeneratedValue
private Long id;
private String content;
@ManyToMany
@JoinTable(
name = "comment_keyword",
joinColumns = @JoinColumn(name="comment_id"),
inverseJoinColumns = @JoinColumn(name="keyword_id")
)
private Set<Keyword> keywords = new HashSet<>();
}
public interface CommentRepo extends CrudRepository<Comment, Long>{
}
연관관계인 Keyword Entity도 만들어준다.
@Entity
@Getter
public class Keyword {
@Id
@GeneratedValue
private Long id;
@Column(unique = true)
private String name;
}
public interface KeywordRepo extends CrudRepository<Keyword, Long>{
}
applicaiton.yml 설정
spring:
datasource:
url: jdbc:postgresql://host:port/database
username: username
password: password
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
data:
rest:
base-path: /api
logging:
level:
root: debug
Entity 조회
해당 entity의 컬럼들 뿐만 아니라, 관련된 API 정보까지 반환해주는 Restful 원칙을 지킨 것을 볼 수 있다. 이 점은 프론트엔드 측에서 연관된 API가 무엇인지 쉽게 알 수 있는 유용한 기능이다.
curl --location --request GET 'http://192.168.78.154:8080/api/comments'
{
"_embedded": {
"comments": [
{
"content": "This is the content.",
"_links": {
"self": {
"href": "http://192.168.78.154:8080/api/comments/1"
},
"comment": {
"href": "http://192.168.78.154:8080/api/comments/1"
},
"keywords": {
"href": "http://192.168.78.154:8080/api/comments/1/keywords"
}
}
}
]
},
"_links": {
"self": {
"href": "http://192.168.78.154:8080/api/comments"
},
"profile": {
"href": "http://192.168.78.154:8080/api/profile/comments"
}
}
}
Entity 데이터 추가
curl --location --request POST 'http://192.168.78.154:8080/api/comments' \
--header 'Content-Type: application/json' \
--data-raw '{
"content": "this is content."
}'
{
"content": "this is content.",
"_links": {
"self": {
"href": "http://192.168.78.154:8080/api/comments/1"
},
"comment": {
"href": "http://192.168.78.154:8080/api/comments/1"
},
"keywords": {
"href": "http://192.168.78.154:8080/api/comments/1/keywords"
}
}
}
Entity 관계 추가
Entity 간 연관관계를 추가하려면, 먼저 해당 Entity를 추가한다음에 해야한다.
Content-Type으로 text/uri-list
를 사용한다.
curl --location --request PUT 'http://192.168.78.154:8080/api/comments/1/keywords' \
--header 'Content-Type: text/uri-list' \
--data-raw 'http://192.168.78.154:8080/api/keywords/2
http://192.168.78.154:8080/api/keywords/4'
Response Body는 비어있다.
Entity 연관 관계 조회
해당 Entity의 연관관계를 조회하려면 다른 URI로 조회해야 한다. 컬럼과 연관관계를 함꺼번에 조회하고자 하는 것이 바로 안된다는 점이 불편한 점인 것 같다. 하지만 이것이 Restful 한 방식. Spring Data REST에서 따로 설정을 해야할 것 같다.
curl --location --request GET 'http://192.168.78.154:8080/api/comments/1/keywords' \
--header 'Content-Type: text/uri-list'
{
"_embedded": {
"keywords": [
{
"name": "keyword2",
"_links": {
"self": {
"href": "http://192.168.78.154:8080/api/keywords/4"
},
"keyword": {
"href": "http://192.168.78.154:8080/api/keywords/4"
}
}
},
{
"name": "keyword1",
"_links": {
"self": {
"href": "http://192.168.78.154:8080/api/keywords/2"
},
"keyword": {
"href": "http://192.168.78.154:8080/api/keywords/2"
}
}
}
]
},
"_links": {
"self": {
"href": "http://192.168.78.154:8080/api/comments/1/keywords"
}
}
}
사용 후기
장점
- Restful 원칙을 지킨 Restful API를 빠르게 만들 수 있다.
- Restful API이기 때문에, 연관된 API 정보를 요청자가 알 수 있으므로, API 문서를 열지 않아도 된다.
단점
- 데이터를 추가하고, 연관관계를 만들어야 한다. API를 2번 호출해야하는 불편함이 있다. API 사용자 입장에서 불편할 수도 있다.
- 다양한 view 의 요청을 대응하기 힘들다. 고정된 Restful 형식을 가지기 때문에, 따로 설정을 바꿔야 한다. 따로 설정을 바꾸는 것보다 MVC 프레임워크를 사용하는 것이 더 수월하다.
'공부노트' 카테고리의 다른 글
ruby server 실행 시, bundler 실행 버그 (0) | 2021.02.24 |
---|---|
Git Revert 와 Reset (0) | 2021.02.24 |
Ruby 데이터 타입 (0) | 2020.10.03 |
Windows Subsystem for Linux(WSL) 은 어떻게 동작할까? (0) | 2020.09.20 |
전기적 컴퓨팅 - 컴퓨터 역사 (0) | 2020.01.27 |