[Spring] API Version management ๐Ÿ“‘

9468 ๋‹จ์–ด SpringSpring

REST API ์„ค๊ณ„ or application ๊ตฌ์กฐ ๋ณ€๊ฒฝ ์‹œ ๐Ÿ‘‰ ๋ฒ„์ „ ๋ณ€๊ฒฝ

์‚ฌ์šฉ์ž ๐Ÿ‘‰ API์˜ ๋ฒ„์ „ ๋ช…์‹œ



Versioning


  • URI Versioning - (Twitter) ์ผ๋ฐ˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ

  • Request Parameter Versioning - (Amazon) ์ผ๋ฐ˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ

  • (Custom) Headers Versioning - (Microsoft) ์ผ๋ฐ˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๋ถˆ๊ฐ€

  • Media Type Versioning - (GitHub) ์ผ๋ฐ˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๋ถˆ๊ฐ€





@RequestMapping("/admin") ๐Ÿ‘‰ ๊ฐ€์ •



UserV2 Class

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonFilter("UserInfoV2")
public class UserV2 extends User{

    private String grade;

}



  • URI์— ๋ฒ„์ „์„ ํฌํ•จํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ

@GetMapping("/v2/users/{id}")
    public MappingJacksonValue retrieveUsersV2(@PathVariable int id){

        User user = service.findOne(id);

        if(user == null){
            throw new UserNotFoundException(String.format("ID[%s] not found", id));
        }

        // User -> UserV2
        UserV2 userV2 = new UserV2();

        BeanUtils.copyProperties(user, userV2); // id, name, joinDate, password, ssn
        userV2.setGrade("VIP");

        SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter
                .filterOutAllExcept("id", "name", "password","grade");

        FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfoV2", filter);

        MappingJacksonValue mapping = new MappingJacksonValue(userV2);
        mapping.setFilters(filters);

        return mapping;
    }

ex) http://localhost:3033/admin/v2/users/1 ๐Ÿ‘‰ ์ž…๋ ฅ

}



  • Request Parameter๋ฅผ ์ด์šฉํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ

@GetMapping(value = "/users/{id}/", params = "version=2") ๐Ÿ‘‰ ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝ

ex) http://localhost:3033/admin/users/1/?version=2 ๐Ÿ‘‰ ์ž…๋ ฅ



  • header ๊ฐ’์„ ์ด์šฉํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ

@GetMapping(value = "/users/{id}", headers = "X-API-VERSION=2") ๐Ÿ‘‰ ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝ

ex) http://localhost:3033/admin/users/1 ๐Ÿ‘‰ Header ๊ฐ’ (KEY : X-API-VERSION, VALUE : 2) ์ž…๋ ฅ



  • Mime Type์„ ์ด์šฉํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ

@GetMapping(value = "/users/{id}", produces = "application/vnd.company.appv2+json")

ex) http://localhost:3033/admin/users/1 
๐Ÿ‘‰ Header ๊ฐ’ (KEY : Accept, VALUE : application/vnd.company.appv2+json) ์ž…๋ ฅ

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ