content: package io.vividcode.happyride.addressservice.web;
  
  import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
  import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
  
  import io.vividcode.happyride.addressservice.api.AddressVO;
  import io.vividcode.happyride.addressservice.api.AreaVO;
  import io.vividcode.happyride.addressservice.api.web.AddressBatchRequest;
  import io.vividcode.happyride.addressservice.service.AddressService;
  import io.vividcode.happyride.addressservice.service.AreaService;
  import java.util.List;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.hateoas.EntityModel;
  import org.springframework.http.ResponseEntity;
  import org.springframework.web.bind.annotation.GetMapping;
  import org.springframework.web.bind.annotation.PathVariable;
  import org.springframework.web.bind.annotation.PostMapping;
  import org.springframework.web.bind.annotation.RequestBody;
  import org.springframework.web.bind.annotation.RequestParam;
  import org.springframework.web.bind.annotation.RestController;
  
  @RestController
  public class AddressController {
  
    @Autowired
    AddressService addressService;
  
    @Autowired
    AreaService areaService;
  
    @GetMapping("/search")
    public List<AddressVO> search(
        @RequestParam("areaCode") final Long areaCode,
        @RequestParam("query") final String query) {
      return this.addressService.search(areaCode, query);
    }
  
    @GetMapping("/address/{addressId}")
    public ResponseEntity<EntityModel<AddressVO>> getAddress(
        @PathVariable("addressId") final String addressId,
        @RequestParam(value = "areaLevel", required = false, defaultValue = "1") final int areaLevel) {
      return this.addressService.getAddress(addressId, areaLevel)
          .map(address -> EntityModel.of(address,
              linkTo(methodOn(AddressController.class).getAddress(addressId, areaLevel)).withSelfRel()))
          .map(ResponseEntity::ok)
          .orElseGet(() -> ResponseEntity.notFound().build());
    }
  
    @PostMapping("/addresses")
    public List<AddressVO> getAddresses(
        @RequestBody final AddressBatchRequest addressBatchRequest) {
      return this.addressService
          .getAddresses(addressBatchRequest.getAddressIds());
    }
  
    @GetMapping("/area/{areaCode}")
    public ResponseEntity<AreaVO> getArea(
        @PathVariable("areaCode") final Long areaCode,
        @RequestParam(value = "ancestorLevel", required = false, defaultValue = "0") final int ancestorLevel) {
      return this.areaService.getArea(areaCode, ancestorLevel)
          .map(ResponseEntity::ok)
          .orElseGet(() -> ResponseEntity.notFound().build());
    }
  }
  