[横書きアイテム]そんなREST APIで大丈夫ですか?本格的なREST APIの実装:Index Controllerの実装(エントリポイント)

21498 ワード

APIエントリポイントインデックスの実装


APIを使用するには、APIから初期データ(どのAPIに関する情報)のインデックスを取得できる必要がある.
このため、IndexControllerを実装し、イベントドメインリンクとProfileリンクを追加します.

テストコードの作成


考慮すべき事項
  • Indexプロファイルリンクありますか?
  • インデックスにイベントリンクはありますか?
  • このため、イベントコードは次のように記述されます.
    
    @SpringBootTest
    @AutoConfigureMockMvc
    @ActiveProfiles("test")
    class IndexControllerTest {
    
        @Autowired
        private MockMvc mockMvc;
    
        @Test
        public void index() throws Exception {
            this.mockMvc.perform(get("/api"))
                    .andDo(print())
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("_links.profile").exists())
                    .andExpect(jsonPath("_links.events").exists());
        }
    
    }

    ymlファイルを使用してURL依存性を注入


    前回イベントコントローラの再設計と実装の際、Swagger URLを直接追加しました.
    これは悪い方法なので、ymlファイルを使用してurlを注入します.
    swagger:
      index: /swagger-ui/index.html#
      event:
        create: /swagger-ui/index.html#/Event%20Controller/createUsingPOST
        readAll: /swagger-ui/index.html#/Event%20Controller/readAllUsingGET
        read: /swagger-ui/index.html#/Event%20Controller/readUsingGET
        update: /swagger-ui/index.html#/Event%20Controller/updateUsingPUT
    まずEvent Controlを変更します.
    @Api(tags = {"Event Controller"})
    @RestController()
    @RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_VALUE)
    public class EventController {
    
        @Autowired
        private EventService eventService;
    
        @Value("${swagger.event.create}")
        private String swaggerCreateEventURL;
    
        @Value("${swagger.event.update}")
        private String swaggerUpdateEventURL;
    
        @Value("${swagger.event.readAll}")
        private String swaggerReadAllEventURL;
    
        @Value("${swagger.event.read}")
        private String swaggerReadEventURL;
    
        @ApiOperation(value = "Event 객체를 추가하는 메소드")
        @PostMapping("")
        public ResponseEntity create(@RequestBody @Valid EventDto eventDto) {
            Event event = this.eventService.create(eventDto);
            EventResource eventResource = createEventResource(event, swaggerCreateEventURL);
            URI uri = getCreateAndUpdateLink(eventResource).toUri();
            return ResponseEntity.created(uri).body(eventResource);
        }
    
        @ApiOperation(value = "모든 Event 객체를 읽어오는 메소드")
        @GetMapping("")
        public ResponseEntity readAll(Pageable pageable, PagedResourcesAssembler pagedResourcesAssembler) {
            var result =  createPagingModel(pageable, pagedResourcesAssembler);
            addProfileLink(result, swaggerUpdateEventURL);
            return ResponseEntity.ok(result);
        }
    
        @ApiOperation(value = "Event 단일 객체를 읽어오는 메소드")
        @GetMapping("/{id}")
        public ResponseEntity read(@PathVariable Integer id){
            Event event = this.eventService.read(id);
            EventResource eventResource = createEventResource(event, swaggerReadAllEventURL);
            return ResponseEntity.ok(eventResource);
        }
    
        @ApiOperation(value = "이벤트 객체를 수정하는 메소드")
        @PutMapping("/{id}")
        public ResponseEntity update(@RequestBody @Valid EventDto eventDto, @PathVariable Integer id){
            Event event = this.eventService.update(id, eventDto);
            EventResource eventResource = createEventResource(event, swaggerReadEventURL);
            return ResponseEntity.ok(eventResource);
        }
    	...
    }

    IndexControllerの実施とテスト結果

    @RestController()
    @RequestMapping(value = "/api", produces = MediaTypes.HAL_JSON_VALUE)
    public class IndexController {
        @Value("${swagger.index}")
        private String swaggerIndexURL;
    
        @GetMapping("")
        public ResponseEntity index(){
            return ResponseEntity.ok()
                    .body(new RepresentationModel()
                            .add(new Link(getBaseURL() + swaggerIndexURL).withRel("profile"))
                            .add(linkTo(EventController.class).withRel("events")));
        }
        private String getBaseURL(){
            return ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString();
        }
    
    }