diff --git a/README.md b/README.md index 4f332c2..51201de 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,12 @@ We will walk through the different steps required to get the application running git clone https://github.com/couchbase-examples/java-springboot-quickstart.git ``` +### Navigate to the Project Directory + +```shell +cd java-springboot-quickstart +``` + ### Install Dependencies The dependencies for the application are specified in the `pom.xml` file in the root folder. Dependencies can be installed through `mvn` the default package manager for Java. diff --git a/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java b/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java index 26dbc3c..98f2bc1 100644 --- a/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java +++ b/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java @@ -2,11 +2,8 @@ import java.util.List; -import jakarta.validation.Valid; - import org.couchbase.quickstart.springboot.models.Airline; import org.couchbase.quickstart.springboot.services.AirlineService; -import org.springframework.context.annotation.Description; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -23,6 +20,10 @@ import com.couchbase.client.core.error.DocumentNotFoundException; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; @RestController @@ -41,9 +42,15 @@ public AirlineController(AirlineService airlineService) { private static final String DOCUMENT_NOT_FOUND = "Document Not Found"; @GetMapping("/{id}") - @Operation(summary = "Get an airline by ID") - @Description(value = "Get Airline by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to retrieve a document with a specified ID. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `getAirline`") - public ResponseEntity getAirline(@PathVariable String id) { + @Operation(summary = "Get an airline by ID", description = "Get Airline by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to retrieve a document with a specified ID. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `getAirline`", tags = { + "Airline" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Airline found"), + @ApiResponse(responseCode = "404", description = "Airline not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "Airline ID", required = true, example = "airline_10") + public ResponseEntity getAirline(@PathVariable(required = true) String id) { try { Airline airline = airlineService.getAirlineById(id); if (airline != null) { @@ -62,8 +69,14 @@ public ResponseEntity getAirline(@PathVariable String id) { } @PostMapping("/{id}") - @Operation(summary = "Create an airline") - @Description(value = "Create Airport with specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to create a new document with a specified ID. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `createAirline`") + @Operation(summary = "Create an airline", description = "Create Airport with specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to create a new document with a specified ID. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `createAirline`", tags = { + "Airline" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Airline created"), + @ApiResponse(responseCode = "409", description = "Airline already exists"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "Airline ID", required = true, example = "airline_10") public ResponseEntity createAirline(@PathVariable String id, @Valid @RequestBody Airline airline) { try { Airline newAirline = airlineService.createAirline(airline); @@ -79,8 +92,14 @@ public ResponseEntity createAirline(@PathVariable String id, @Valid @Re } @PutMapping("/{id}") - @Operation(summary = "Update an airline") - @Description(value = "Update Airport with specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to update a document with a specified ID. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `updateAirline`") + @Operation(summary = "Update an airline", description = "Update Airport with specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to update a document with a specified ID. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `updateAirline`", tags = { + "Airline" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Airline updated"), + @ApiResponse(responseCode = "404", description = "Airline not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "Airline ID", required = true, example = "airline_10") public ResponseEntity updateAirline(@PathVariable String id, @Valid @RequestBody Airline airline) { try { Airline updatedAirline = airlineService.updateAirline(id, airline); @@ -99,8 +118,14 @@ public ResponseEntity updateAirline(@PathVariable String id, @Valid @Re } @DeleteMapping("/{id}") - @Operation(summary = "Delete an airline") - @Description(value = "Delete Airport with specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to delete a document with a specified ID. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `deleteAirline`") + @Operation(summary = "Delete an airline", description = "Delete Airport with specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to delete a document with a specified ID. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `deleteAirline`", tags = { + "Airline" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Airline deleted"), + @ApiResponse(responseCode = "404", description = "Airline not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "Airline ID", required = true, example = "airline_10") public ResponseEntity deleteAirline(@PathVariable String id) { try { airlineService.deleteAirline(id); @@ -115,28 +140,23 @@ public ResponseEntity deleteAirline(@PathVariable String id) { } @GetMapping("/list") - @Operation(summary = "List all airlines") - @Description(value = "List all Airports.\n\nThis provides an example of using N1QL to query all documents of a specific type. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `listAirlines`") - public ResponseEntity> listAirlines( + @Operation(summary = "List all airlines by country", description = "List all Airports by country.\n\nThis provides an example of using N1QL to query all documents of a specific type by a specific field. \n\n Code: `controllers/AirlineController.java` \n File: `AirlineController.java` \n Method: `listAirlinesByCountry`", tags = { + "Airline" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Airlines found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "country", description = "Country", required = false, example = "United States") + public ResponseEntity> listAirlinesByCountry(@RequestParam(required = false) String country, @RequestParam(defaultValue = "10") int limit, @RequestParam(defaultValue = "0") int offset) { try { - List airlines = airlineService.listAirlines(limit, offset); - return new ResponseEntity<>(airlines, HttpStatus.OK); - } catch (Exception e) { - log.error(INTERNAL_SERVER_ERROR + ": " + e.getMessage()); - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } - } - - @Operation(summary = "List all airlines by country") - @GetMapping("/country/{country}") - @Description(value = "List all Airports by country.\n\nThis provides an example of using N1QL to query all documents of a specific type by a specific field. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `listAirlinesByCountry`") - public ResponseEntity> listAirlinesByCountry(@PathVariable String country, - @RequestParam(defaultValue = "10") int limit, - @RequestParam(defaultValue = "0") int offset) { - try { - List airlines = airlineService.listAirlinesByCountry(country, limit, offset); + List airlines; + if (country == null || country.isEmpty()) { + airlines = airlineService.listAirlines(limit, offset); + } else { + airlines = airlineService.listAirlinesByCountry(country, limit, offset); + } return new ResponseEntity<>(airlines, HttpStatus.OK); } catch (Exception e) { log.error(INTERNAL_SERVER_ERROR + ": " + e.getMessage()); @@ -144,11 +164,16 @@ public ResponseEntity> listAirlinesByCountry(@PathVariable String } } - @Operation(summary = "List all airlines by destination airport") - @GetMapping("/destination/{destinationAirport}") - @Description(value = "List all Airports by destination airport.\n\nThis provides an example of using N1QL to query all documents of a specific type by a specific field. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `listAirlinesByDestinationAirport`") + @GetMapping("/to-airport") + @Operation(summary = "List all airlines by destination airport", description = "List all Airports by destination airport.\n\nThis provides an example of using N1QL to query all documents of a specific type by a specific field. \n\n Code: [`controllers/AirlineController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirlineController.java) \n File: `AirlineController.java` \n Method: `listAirlinesByDestinationAirport`", tags = { + "Airline" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Airlines found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "destinationAirport", description = "Destination Airport", required = true, example = "SFO") public ResponseEntity> listAirlinesByDestinationAirport( - @PathVariable String destinationAirport, + @RequestParam(required = true) String destinationAirport, @RequestParam(defaultValue = "10") int limit, @RequestParam(defaultValue = "0") int offset) { try { diff --git a/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java b/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java index 06b4b07..2db9bfd 100644 --- a/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java +++ b/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java @@ -3,12 +3,9 @@ import java.util.List; import java.util.stream.Collectors; -import jakarta.validation.Valid; - import org.couchbase.quickstart.springboot.models.Airport; import org.couchbase.quickstart.springboot.models.Route; import org.couchbase.quickstart.springboot.services.AirportService; -import org.springframework.context.annotation.Description; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -25,6 +22,10 @@ import com.couchbase.client.core.error.DocumentNotFoundException; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; @RestController @@ -43,8 +44,14 @@ public AirportController(AirportService airportService) { private static final String DOCUMENT_NOT_FOUND = "Document Not Found"; @GetMapping("/{id}") - @Operation(summary = "Get an airport by ID") - @Description(value = "Get Airport by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to retrieve a document with a specified ID. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `getAirport`") + @Operation(summary = "Get an airport by ID", description = "Get Airport by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to retrieve a document with a specified ID. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `getAirport`", tags = { + "Airport" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Airport found"), + @ApiResponse(responseCode = "404", description = "Airport not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "The ID of the airport to retrieve", required = true, example = "airport_1254") public ResponseEntity getAirport(@PathVariable String id) { try { Airport airport = airportService.getAirportById(id); @@ -64,8 +71,14 @@ public ResponseEntity getAirport(@PathVariable String id) { } @PostMapping("/{id}") - @Operation(summary = "Create an airport") - @Description(value = "Create Airport by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to create a document with a specified ID. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `createAirport`") + @Operation(summary = "Create an airport", description = "Create Airport by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to create a document with a specified ID. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `createAirport`", tags = { + "Airport" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Airport created"), + @ApiResponse(responseCode = "409", description = "Airport already exists"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "The ID of the airport to create", required = true, example = "airport_1254") public ResponseEntity createAirport(@PathVariable String id, @Valid @RequestBody Airport airport) { try { Airport newAirport = airportService.createAirport(airport); @@ -80,9 +93,15 @@ public ResponseEntity createAirport(@PathVariable String id, @Valid @Re } - @Operation(summary = "Update an airport") @PutMapping("/{id}") - @Description(value = "Update Airport by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to update a document with a specified ID. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `updateAirport`") + @Operation(summary = "Update an airport", description = "Update Airport by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to update a document with a specified ID. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `updateAirport`", tags = { + "Airport" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Airport updated"), + @ApiResponse(responseCode = "404", description = "Airport not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "The ID of the airport to update", required = true, example = "airport_1254") public ResponseEntity updateAirport(@PathVariable String id, @Valid @RequestBody Airport airport) { try { Airport updatedAirport = airportService.updateAirport(id, airport); @@ -101,8 +120,14 @@ public ResponseEntity updateAirport(@PathVariable String id, @Valid @Re } @DeleteMapping("/{id}") - @Operation(summary = "Delete an airport") - @Description(value = "Delete Airport by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to delete a document with a specified ID. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `deleteAirport`") + @Operation(summary = "Delete an airport", description = "Delete Airport by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to delete a document with a specified ID. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `deleteAirport`", tags = { + "Airport" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Airport deleted"), + @ApiResponse(responseCode = "404", description = "Airport not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "The ID of the airport to delete", required = true, example = "airport_1254") public ResponseEntity deleteAirport(@PathVariable String id) { try { airportService.deleteAirport(id); @@ -117,8 +142,12 @@ public ResponseEntity deleteAirport(@PathVariable String id) { } @GetMapping("/list") - @Operation(summary = "List all airports") - @Description(value = "List all Airports.\n\nThis provides an example of using N1QL queries in Couchbase to retrieve all documents of a specified type. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `listAirports`") + @Operation(summary = "List all airports", description = "List all Airports.\n\nThis provides an example of using N1QL queries in Couchbase to retrieve all documents of a specified type. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `listAirports`", tags = { + "Airport" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Airports found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) public ResponseEntity> listAirports( @RequestParam(defaultValue = "10") int limit, @RequestParam(defaultValue = "0") int offset) { @@ -131,10 +160,15 @@ public ResponseEntity> listAirports( } } - @GetMapping("/direct-connections/{airportCode}") - @Operation(summary = "List all direct connections from an airport") - @Description(value = "List all direct connections from an Airport.\n\nThis provides an example of using N1QL queries in Couchbase to retrieve all documents of a specified type. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `listDirectConnections`") - public ResponseEntity> listDirectConnections(@PathVariable String airportCode, + @GetMapping("/direct-connections") + @Operation(summary = "List all direct connections from an airport", description = "List all direct connections from an airport.\n\nThis provides an example of using N1QL queries in Couchbase to retrieve all documents of a specified type. \n\n Code: [`controllers/AirportController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/AirportController.java) \n File: `AirportController.java` \n Method: `listDirectConnections`", tags = { + "Airport" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Direct connections found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "airportCode", description = "The code of the airport to retrieve direct connections from", required = true, example = "SFO") + public ResponseEntity> listDirectConnections(@RequestParam(required = true) String airportCode, @RequestParam(defaultValue = "10") int limit, @RequestParam(defaultValue = "0") int offset) { try { diff --git a/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java b/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java index ca34b43..5b825c9 100644 --- a/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java +++ b/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java @@ -2,12 +2,8 @@ import java.util.List; -// import javax.validation.Valid; -import jakarta.validation.Valid; - import org.couchbase.quickstart.springboot.models.Route; import org.couchbase.quickstart.springboot.services.RouteService; -import org.springframework.context.annotation.Description; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -24,6 +20,10 @@ import com.couchbase.client.core.error.DocumentNotFoundException; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; @RestController @@ -42,8 +42,14 @@ public RouteController(RouteService routeService) { private static final String DOCUMENT_NOT_FOUND = "Document Not Found"; @GetMapping("/{id}") - @Operation(summary = "Get a route by ID") - @Description(value = "Get Route by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to retrieve a document with a specified ID. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `getRoute`") + @Operation(summary = "Get a route by ID", description = "Get Route by specified ID.\n\nThis provides an example of using Key Value operations in Couchbase to retrieve a document with a specified ID. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `getRoute`", tags = { + "Route" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Route found"), + @ApiResponse(responseCode = "404", description = "Route not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "Route ID", required = true, example = "route_10000") public ResponseEntity getRoute(@PathVariable String id) { try { Route route = routeService.getRouteById(id); @@ -63,8 +69,14 @@ public ResponseEntity getRoute(@PathVariable String id) { } @PostMapping("/{id}") - @Operation(summary = "Create a route") - @Description(value = "Create a new Route.\n\nThis provides an example of using Key Value operations in Couchbase to create a new document with a specified ID. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `createRoute`") + @Operation(summary = "Create a route", description = "Create a Route.\n\nThis provides an example of using Key Value operations in Couchbase to create a new document with a specified ID. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `createRoute`", tags = { + "Route" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Route created"), + @ApiResponse(responseCode = "409", description = "Route already exists"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "Route ID", required = true, example = "route_10000") public ResponseEntity createRoute(@PathVariable String id, @Valid @RequestBody Route route) { try { Route newRoute = routeService.createRoute(route); @@ -80,8 +92,14 @@ public ResponseEntity createRoute(@PathVariable String id, @Valid @Reques } @PutMapping("/{id}") - @Operation(summary = "Update a route") - @Description(value = "Update a Route.\n\nThis provides an example of using Key Value operations in Couchbase to update a document with a specified ID. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `updateRoute`") + @Operation(summary = "Update a route", description = "Update a Route.\n\nThis provides an example of using Key Value operations in Couchbase to update a document with a specified ID. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `updateRoute`", tags = { + "Route" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Route updated"), + @ApiResponse(responseCode = "404", description = "Route not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "Route ID", required = true, example = "route_10000") public ResponseEntity updateRoute(@PathVariable String id, @Valid @RequestBody Route route) { try { Route updatedRoute = routeService.updateRoute(id, route); @@ -100,8 +118,14 @@ public ResponseEntity updateRoute(@PathVariable String id, @Valid @Reques } @DeleteMapping("/{id}") - @Operation(summary = "Delete a route") - @Description(value = "Delete a Route.\n\nThis provides an example of using Key Value operations in Couchbase to delete a document with a specified ID. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `deleteRoute`") + @Operation(summary = "Delete a route", description = "Delete a Route.\n\nThis provides an example of using Key Value operations in Couchbase to delete a document with a specified ID. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `deleteRoute`", tags = { + "Route" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Route deleted"), + @ApiResponse(responseCode = "404", description = "Route not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) + @Parameter(name = "id", description = "Route ID", required = true, example = "route_10000") public ResponseEntity deleteRoute(@PathVariable String id) { try { routeService.deleteRoute(id); @@ -116,8 +140,12 @@ public ResponseEntity deleteRoute(@PathVariable String id) { } @GetMapping("/list") - @Operation(summary = "List all routes") - @Description(value = "List all Routes.\n\nThis provides an example of using Key Value operations in Couchbase to list all documents. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/master/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `listRoutes`") + @Operation(summary = "List all routes", description = "List all Routes.\n\nThis provides an example of using N1QL queries in Couchbase to retrieve all documents of a specified type. \n\n Code: [`controllers/RouteController.java`](https://github.com/couchbase-examples/java-springboot-quickstart/blob/main/src/main/java/org/couchbase/quickstart/springboot/controllers/RouteController.java) \n File: `RouteController.java` \n Method: `listRoutes`", tags = { + "Route" }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Routes found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error") + }) public ResponseEntity> listRoutes( @RequestParam(defaultValue = "10") int limit, @RequestParam(defaultValue = "0") int offset) { diff --git a/src/main/java/org/couchbase/quickstart/springboot/repositories/AirlineRepositoryImpl.java b/src/main/java/org/couchbase/quickstart/springboot/repositories/AirlineRepositoryImpl.java index b5305a0..15ab131 100644 --- a/src/main/java/org/couchbase/quickstart/springboot/repositories/AirlineRepositoryImpl.java +++ b/src/main/java/org/couchbase/quickstart/springboot/repositories/AirlineRepositoryImpl.java @@ -10,7 +10,6 @@ import com.couchbase.client.java.Cluster; import com.couchbase.client.java.Collection; import com.couchbase.client.java.json.JsonArray; -import com.couchbase.client.java.json.JsonObject; import com.couchbase.client.java.query.QueryOptions; import com.couchbase.client.java.query.QueryScanConsistency; @@ -52,22 +51,23 @@ public void delete(String id) { @Override public List findAll(int limit, int offset) { String statement = "SELECT airline.id, airline.type, airline.name, airline.iata, airline.icao, airline.callsign, airline.country FROM `" - + couchbaseConfig.getBucketName() + "`.`inventory`.`airline` LIMIT " + limit + " OFFSET " + offset; + + couchbaseConfig.getBucketName() + "`.`inventory`.`airline` LIMIT $1 OFFSET $2"; return cluster - .query(statement, QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS)) + .query(statement, + QueryOptions.queryOptions().parameters(JsonArray.from(limit, offset)) + .scanConsistency(QueryScanConsistency.REQUEST_PLUS)) .rowsAs(Airline.class); } @Override public List findByCountry(String country, int limit, int offset) { String statement = "SELECT airline.id, airline.type, airline.name, airline.iata, airline.icao, airline.callsign, airline.country FROM `" - + couchbaseConfig.getBucketName() + "`.`inventory`.`airline` WHERE country = '" + country + "' LIMIT " - + limit + " OFFSET " + offset; + + couchbaseConfig.getBucketName() + "`.`inventory`.`airline` WHERE country = $1 LIMIT $2 OFFSET $3"; return cluster - .query(statement, QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS) - .parameters(JsonObject.create().put("country", country))) + .query(statement, + QueryOptions.queryOptions().parameters(JsonArray.from(country, limit, offset)) + .scanConsistency(QueryScanConsistency.REQUEST_PLUS)) .rowsAs(Airline.class); - } @Override @@ -79,11 +79,11 @@ public List findByDestinationAirport(String destinationAirport, int lim " ON route.airlineid = META(airline).id " + " WHERE route.destinationairport = $1) AS subquery " + "JOIN `" + couchbaseConfig.getBucketName() + "`.`inventory`.`airline` AS air " + - "ON META(air).id = subquery.airlineId LIMIT " + limit + " OFFSET " + offset; + "ON META(air).id = subquery.airlineId LIMIT $2 OFFSET $3"; return cluster.query( statement, - QueryOptions.queryOptions().parameters(JsonArray.from(destinationAirport)) + QueryOptions.queryOptions().parameters(JsonArray.from(destinationAirport, limit, offset)) .scanConsistency(QueryScanConsistency.REQUEST_PLUS)) .rowsAs(Airline.class); } diff --git a/src/main/java/org/couchbase/quickstart/springboot/repositories/AirportRepositoryImpl.java b/src/main/java/org/couchbase/quickstart/springboot/repositories/AirportRepositoryImpl.java index 6481b29..368c4a3 100644 --- a/src/main/java/org/couchbase/quickstart/springboot/repositories/AirportRepositoryImpl.java +++ b/src/main/java/org/couchbase/quickstart/springboot/repositories/AirportRepositoryImpl.java @@ -9,6 +9,7 @@ import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; import com.couchbase.client.java.Collection; +import com.couchbase.client.java.json.JsonArray; import com.couchbase.client.java.query.QueryOptions; import com.couchbase.client.java.query.QueryScanConsistency; @@ -49,10 +50,12 @@ public void delete(String id) { @Override public List findAll(int limit, int offset) { - String statement = "SELECT airport.* FROM `" + couchbaseConfig.getBucketName() + "`.`inventory`.`airport` LIMIT " - + limit + " OFFSET " + offset; + String statement = "SELECT airport.* FROM `" + couchbaseConfig.getBucketName() + + "`.`inventory`.`airport` LIMIT $1 OFFSET $2"; return cluster - .query(statement, QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS)) + .query(statement, + QueryOptions.queryOptions().parameters(JsonArray.from(limit, offset)) + .scanConsistency(QueryScanConsistency.REQUEST_PLUS)) .rowsAs(Airport.class); } @@ -60,11 +63,12 @@ public List findAll(int limit, int offset) { public List findDirectConnections(String airportCode, int limit, int offset) { String statement = "SELECT route.* FROM `" + couchbaseConfig.getBucketName() + "`.`inventory`.`airport` as airport JOIN `" + couchbaseConfig.getBucketName() - + "`.`inventory`.`route` as route on route.sourceairport = airport.faa WHERE airport.faa = \"" - + airportCode + "\" and route.stops = 0 LIMIT " + limit + " OFFSET " + offset; + + "`.`inventory`.`route` as route on route.sourceairport = airport.faa WHERE airport.faa = $1 and route.stops = 0 LIMIT $2 OFFSET $3"; return cluster - .query(statement, QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS)) + .query(statement, + QueryOptions.queryOptions().parameters(JsonArray.from(airportCode, limit, offset)) + .scanConsistency(QueryScanConsistency.REQUEST_PLUS)) .rowsAs(Route.class); - } + } diff --git a/src/main/java/org/couchbase/quickstart/springboot/repositories/RouteRepositoryImpl.java b/src/main/java/org/couchbase/quickstart/springboot/repositories/RouteRepositoryImpl.java index 5306632..1c437c0 100644 --- a/src/main/java/org/couchbase/quickstart/springboot/repositories/RouteRepositoryImpl.java +++ b/src/main/java/org/couchbase/quickstart/springboot/repositories/RouteRepositoryImpl.java @@ -9,6 +9,7 @@ import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; import com.couchbase.client.java.Collection; +import com.couchbase.client.java.json.JsonArray; import com.couchbase.client.java.query.QueryOptions; import com.couchbase.client.java.query.QueryScanConsistency; @@ -49,10 +50,12 @@ public void delete(String id) { @Override public List findAll(int limit, int offset) { - String statement = "SELECT route.* FROM `" + couchbaseConfig.getBucketName() + "`.`inventory`.`route` LIMIT " - + limit + " OFFSET " + offset; + String statement = "SELECT route.* FROM `" + couchbaseConfig.getBucketName() + + "`.`inventory`.`route` LIMIT $1 OFFSET $2"; return cluster - .query(statement, QueryOptions.queryOptions().scanConsistency(QueryScanConsistency.REQUEST_PLUS)) + .query(statement, + QueryOptions.queryOptions().parameters(JsonArray.from(limit, offset)) + .scanConsistency(QueryScanConsistency.REQUEST_PLUS)) .rowsAs(Route.class); } } diff --git a/src/test/java/org/couchbase/quickstart/springboot/controllers/AirlineIntegrationTest.java b/src/test/java/org/couchbase/quickstart/springboot/controllers/AirlineIntegrationTest.java index 3fd47c9..44b480f 100644 --- a/src/test/java/org/couchbase/quickstart/springboot/controllers/AirlineIntegrationTest.java +++ b/src/test/java/org/couchbase/quickstart/springboot/controllers/AirlineIntegrationTest.java @@ -196,8 +196,7 @@ void testListAirlinesByCountry() { int limit = 10; int offset = 0; ResponseEntity> response = restTemplate.exchange( - "/api/v1/airline/country/" + country + "?limit=" + limit - + "&offset=" + offset, + "/api/v1/airline/list?country=" + country + "&limit=" + limit + "&offset=" + offset, HttpMethod.GET, null, new ParameterizedTypeReference<>() { }); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); @@ -218,8 +217,7 @@ void testListAirlinesByCountry() { country = "France"; ResponseEntity> response2 = restTemplate.exchange( - "/api/v1/airline/country/" + country + "?limit=" + limit - + "&offset=" + offset, + "/api/v1/airline/list?country=" + country + "&limit=" + limit + "&offset=" + offset, HttpMethod.GET, null, new ParameterizedTypeReference<>() { }); assertThat(response2.getStatusCode()).isEqualTo(HttpStatus.OK); @@ -265,8 +263,8 @@ void testListAirlinesByDestinationAirport() { List expectedAirlines = entry.getValue(); ResponseEntity> response = restTemplate.exchange( - "/api/v1/airline/destination/" + destinationAirport - + "?limit=" + limit + "&offset=" + offset, + "/api/v1/airline/to-airport?destinationAirport=" + destinationAirport + + "&limit=" + limit + "&offset=" + offset, HttpMethod.GET, null, new ParameterizedTypeReference<>() { }); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); diff --git a/src/test/java/org/couchbase/quickstart/springboot/controllers/AirportIntegrationTest.java b/src/test/java/org/couchbase/quickstart/springboot/controllers/AirportIntegrationTest.java index e0df811..2bebba1 100644 --- a/src/test/java/org/couchbase/quickstart/springboot/controllers/AirportIntegrationTest.java +++ b/src/test/java/org/couchbase/quickstart/springboot/controllers/AirportIntegrationTest.java @@ -174,8 +174,8 @@ void testListDirectConnections() { int offset = 0; ResponseEntity> response = restTemplate.exchange( - "/api/v1/airport/direct-connections/" + airportCode - + "?limit=" + limit + "&offset=" + offset, + "/api/v1/airport/direct-connections?airportCode=" + airportCode + "&limit=" + + limit + "&offset=" + offset, HttpMethod.GET, null, new ParameterizedTypeReference<>() { }); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); @@ -187,4 +187,4 @@ void testListDirectConnections() { } } -} +} \ No newline at end of file