카테고리 없음

spring-boot-rest를 해보자!(2)

머룽 2023. 4. 18. 12:31

Spring boot rest 를 이용하여 API 서버를 개발해보자! (2)

1편은 여기 검색을 할때 url에 메소드명이 마음에 들지 않는다. 또한 json 키도 마음에 들지 않는다. 그래서 바꾸고싶다. 그러기 위해선 아래와같이 추가해보자
    @RestResource(path = "nameStartsWith", rel = "name")
    Page<Account> findByNameStartsWith(@Param("name") String name, Pageable pageable);
브라우저로 열어보자 http://localhost:8080/account/search
{
  "_links": {
    "name": { //name으로 변경
      "href": "http://localhost:8080/account/search/nameStartsWith{?name,page,size,sort}", //nameStartsWith 으로 변경
      "templated": true
    },
    "findByname": {
      "href": "http://localhost:8080/account/search/findByname{?first_name,page,size,sort}",
      "templated": true
    },
    "self": {
      "href": "http://localhost:8080/account/search"
    }
  }
}
이렇게 나온걸 확인할 수 있다. 그리고 http://localhost:8080/account/search/nameStartsWith?name=wonwoo 로 들어가보면 wonwoo로 시작하는 데이터가 두개 나올 것이다. 아니 근데 나는 이메일을 안보여주고 싶은 경우도 있다. 흠! 그렇담 아래와 같이 인터페이스 추가하자
@Projection(name = "noEmail", types = { Account.class })
public interface NoEmailAccount {

    String getId();

    String getName();

    String getPassword();
}

그런다음 http://localhost:8080/account/1?projection=noEamil url로 브라우저를 열어보자 그러면 아래와 같이 email이 빠진걸 확인 할 수 있다.
{
  "name": "wonwoo",
  "id": "1",
  "password": "qwer",
  "_links": {
    "self": {
      "href": "http://localhost:8080/account/1"
    },
    "account": {
      "href": "http://localhost:8080/account/1{?projection}",
      "templated": true
    }
  }
}
다음은 Address라는 엔티티를 추가해서 Account 에 주소로 사용할 예정이다.
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {
    @Id
    @GeneratedValue
    @Column(name = "address_id")
    private Long id;

    private String street;

    private String state;

    private String country;
}
그리고 Account 엔티티에 다음과 같이 추가 하자
    @OneToOne
    @JoinColumn(name="address_id")
    private Address address;
그리고 초기화 데이터를 넣어주자!
insert into address(address_id, street, state, country) values(1L, 분당구, 경기도, 대한민국);
insert into address(address_id, street, state, country) values(2L, 강남구, 서울특별시, 대한민국);
insert into account(id, name, email, password, address_id) values(1,wonwoo,wonwoo@test.com,qwer, 1L);
insert into account(id, name, email, password, address_id) values(2,kevin,kevin@test.com,asdf, 2L);
insert into account(id, name, email, password, address_id) values(3,wonwoo1,kevin@test.com,qwqw,1L);
그리고 나서 http://localhost:8080/account/1 확인해보자
{
  "name": "wonwoo",
  "email": "wonwoo@test.com",
  "password": "qwer",
  "address": {
    "street": "분당구",
    "state": "경기도",
    "country": "대한민국"
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/account/1"
    },
    "account": {
      "href": "http://localhost:8080/account/1{?projection}",
      "templated": true
    }
  }
}
이렇게 제대로 나올 것이다. 흠. 근데 address가 마음에 들지 않는다. 한줄로도 나왔으면 좋겠다. 그럼 아까 했던 @Projection을 응용해서 보자 아래와 같이 FullAddress라는 인터페이스 생성한다.
@Projection(name = "fullAddress", types = { Account.class })
public interface FullAddress {

    @Value("#{target.address.country} #{target.address.state} #{target.address.street}")
    String getFullAddress();

    String getName();

    String getEmail();

    String getPassword();
}
그리고 나서 http://localhost:8080/account/1?projection=fullAddress 확인해보면 아래와 같이 한줄로 나왔다.
{
  "name": "wonwoo",
  "password": "qwer",
  "email": "wonwoo@test.com",
  "fullAddress": "대한민국 경기도 분당구",
  "_links": {
    "self": {
      "href": "http://localhost:8080/account/1"
    },
    "account": {
      "href": "http://localhost:8080/account/1{?projection}",
      "templated": true
    }
  }
}
그럼 spring-data-rest-jpa 여기서 마치겠다. 소스는 https://github.com/wonwoo/spring-data-rest-jpa 다운 받을 수 있다 다음엔 몽고도 알아보겠다.