diff --git a/pom.xml b/pom.xml
index 79cd452..38886b1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,11 +12,13 @@
net.jwierzbo.rest
REST-movie-service
0.1
+ jar
Movie app - Spring Boot REST with CRUD example
UTF-8
1.8
+ 2.8.0
@@ -28,6 +30,20 @@
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${swagger.lib.version}
+ compile
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${swagger.lib.version}
+ compile
+
diff --git a/src/main/java/net/jwierzbo/rest/controller/MovieV1RestController.java b/src/main/java/net/jwierzbo/rest/api/MovieV1RestController.java
similarity index 96%
rename from src/main/java/net/jwierzbo/rest/controller/MovieV1RestController.java
rename to src/main/java/net/jwierzbo/rest/api/MovieV1RestController.java
index 4f5f696..3bfb66b 100644
--- a/src/main/java/net/jwierzbo/rest/controller/MovieV1RestController.java
+++ b/src/main/java/net/jwierzbo/rest/api/MovieV1RestController.java
@@ -1,4 +1,4 @@
-package net.jwierzbo.rest.controller;
+package net.jwierzbo.rest.api;
import java.util.List;
@@ -21,6 +21,7 @@
import org.springframework.web.bind.annotation.RestController;
@RestController
+@RequestMapping("/v1") // prefix for api methods
public class MovieV1RestController {
@Autowired
diff --git a/src/main/java/net/jwierzbo/rest/api/MovieV2SwaggerController.java b/src/main/java/net/jwierzbo/rest/api/MovieV2SwaggerController.java
new file mode 100644
index 0000000..1b7e0db
--- /dev/null
+++ b/src/main/java/net/jwierzbo/rest/api/MovieV2SwaggerController.java
@@ -0,0 +1,90 @@
+package net.jwierzbo.rest.api;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import net.jwierzbo.rest.dao.MovieDAO;
+import net.jwierzbo.rest.exception.MovieNotFoundException;
+import net.jwierzbo.rest.model.Movie;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.DeleteMapping;
+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.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/* This is example Controller class with extends description for SwaggerApi
+* These @Api*** annotations are not necessary if we use @ResponseStatus
+* and return Model objects instead of generic response */
+
+@Api(value="MovieController", description="List of favourite Movies")
+@RestController
+@RequestMapping("/v2")
+public class MovieV2SwaggerController {
+
+ @Autowired
+ private MovieDAO movieDAO;
+
+ @ApiOperation(value = "View a list of Movies", response = Movie.class, responseContainer = "List")
+ @GetMapping("/movies")
+ public List getMovies() {
+ return movieDAO.list();
+ }
+
+ @ApiOperation(value = "Search a Movie by ID",response = Movie.class)
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Not Found")})
+ @GetMapping("/movies/{id}")
+ public Movie getMovie(@PathVariable("id") Long id) {
+ Movie movie = checkIfMovieExist(id);
+ return movie;
+ }
+
+ @ApiOperation(value = "Add new Movie",response = Movie.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid input"),
+ @ApiResponse(code = 404, message = "Not Found")})
+ @ApiImplicitParams({
+ // This can be write also as inline @ApiParam - example below in "deleteMovie"
+ @ApiImplicitParam(name = "movie", value = "Movie object to add", required = true, dataType = "Movie",
+ paramType = "body")
+ })
+ @PostMapping(value = "/movies")
+ @ResponseStatus(value = HttpStatus.CREATED)
+ public Movie createMovie(@RequestBody Movie movie) {
+ return movieDAO.create(movie);
+ }
+
+ @ApiOperation(value = "Delete specific movie")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Not Found")})
+ @DeleteMapping("/movies/{id}")
+ @ResponseStatus(value = HttpStatus.NO_CONTENT)
+ public void deleteMovie(@ApiParam(value = "Movie ID", required = true) @PathVariable Long id) {
+ checkIfMovieExist(id);
+ movieDAO.delete(id);
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid input"),
+ @ApiResponse(code = 404, message = "Not Found")})
+ @PutMapping("/movies/{id}")
+ public Movie updateMovie(@PathVariable Long id, @RequestBody Movie movie) {
+ checkIfMovieExist(id);
+ return movieDAO.update(id, movie);
+ }
+
+ private Movie checkIfMovieExist(Long id) {
+ return movieDAO.get(id).orElseThrow(() -> new MovieNotFoundException(id));
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/jwierzbo/rest/config/SwaggerConfig.java b/src/main/java/net/jwierzbo/rest/config/SwaggerConfig.java
new file mode 100644
index 0000000..3f45d60
--- /dev/null
+++ b/src/main/java/net/jwierzbo/rest/config/SwaggerConfig.java
@@ -0,0 +1,46 @@
+package net.jwierzbo.rest.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.bind.annotation.RequestMethod;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.builders.ResponseMessageBuilder;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.Arrays;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+ @Bean
+ public Docket api() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .useDefaultResponseMessages(false)
+ .apiInfo(apiInfo())
+ .globalResponseMessage(RequestMethod.GET,
+ Arrays.asList(new ResponseMessageBuilder()
+ .code(500)
+ .message("Server Error")
+ .build()))
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("net.jwierzbo.rest"))
+ .paths(PathSelectors.any())
+ .build();
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("Favourites movies API")
+ .description("CRUD example REST API to manage list of movies")
+ .contact(new Contact("jwierzbo", "url", "jwierzbo@jwierzbo.net"))
+ .license("MIT")
+ .version("0.1")
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/jwierzbo/rest/model/Movie.java b/src/main/java/net/jwierzbo/rest/model/Movie.java
index 9beb687..3de6174 100644
--- a/src/main/java/net/jwierzbo/rest/model/Movie.java
+++ b/src/main/java/net/jwierzbo/rest/model/Movie.java
@@ -1,58 +1,65 @@
package net.jwierzbo.rest.model;
import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
import java.time.LocalDate;
+@ApiModel(value = "Movie")
public class Movie {
- private Long id;
- private String title;
- private String director;
+ @ApiModelProperty(notes = "The database generated product ID")
+ private Long id;
- @JsonFormat(pattern = "yyyy-MM-dd")
- private LocalDate releaseDate;
+ private String title;
- public Movie(long id, String title, String director, LocalDate releaseDate) {
- this.id = id;
- this.title = title;
- this.director = director;
- this.releaseDate = releaseDate;
- }
+ private String director;
- public Movie() {
- }
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @ApiModelProperty(notes = "Movie premiere date", example = "2018-02-28")
+ private LocalDate releaseDate;
- public Long getId() {
- return id;
- }
+ public Movie(long id, String title, String director, LocalDate releaseDate) {
+ this.id = id;
+ this.title = title;
+ this.director = director;
+ this.releaseDate = releaseDate;
+ }
- public void setId(Long id) {
- this.id = id;
- }
+ public Movie() {
+ }
- public String getTitle() {
- return title;
- }
+ public Long getId() {
+ return id;
+ }
- public void setTitle(String title) {
- this.title = title;
- }
+ public void setId(Long id) {
+ this.id = id;
+ }
- public String getDirector() {
- return director;
- }
+ public String getTitle() {
+ return title;
+ }
- public void setDirector(String director) {
- this.director = director;
- }
+ public void setTitle(String title) {
+ this.title = title;
+ }
- public LocalDate getReleaseDate() {
- return releaseDate;
- }
+ public String getDirector() {
+ return director;
+ }
- public void setReleaseDate(LocalDate releaseDate) {
- this.releaseDate = releaseDate;
- }
+ public void setDirector(String director) {
+ this.director = director;
+ }
+
+ public LocalDate getReleaseDate() {
+ return releaseDate;
+ }
+
+ public void setReleaseDate(LocalDate releaseDate) {
+ this.releaseDate = releaseDate;
+ }
}
\ No newline at end of file