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 다운 받을 수 있다
다음엔 몽고도 알아보겠다.