Skip to content

Commit 0d138cc

Browse files
authored
Merge pull request #17 from AdamZink/develop
Part 4 to master
2 parents 98092f0 + 5dd1232 commit 0d138cc

File tree

7 files changed

+123
-9
lines changed

7 files changed

+123
-9
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ Tutorials are available to explain the steps on [Medium](https://medium.com/@ada
1313
* [Part 1 - Create a Spring Boot application with Spring Initializr](https://medium.com/@adamzink/creating-an-api-with-spring-boot-and-mysql-part-1-4c5544a2a202)
1414
* [Part 2 - Create the first API endpoint to POST a User](https://medium.com/@adamzink/creating-an-api-with-spring-boot-and-mysql-part-2-1b3f5740c7bf)
1515
* [Part 3 - Create more API endpoints to GET, PUT, and DELETE Users](https://medium.com/@adamzink/creating-an-api-with-spring-boot-and-mysql-part-3-f1b5ef9334c0)
16+
* [Part 4 - Add API documentation with Swagger](https://medium.com/@adamzink/creating-an-api-with-spring-boot-and-mysql-part-4-d39edbe87b53)

pom.xml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@
5656
<artifactId>spring-boot-starter-test</artifactId>
5757
<scope>test</scope>
5858
</dependency>
59+
60+
<!-- Added for Part 4 -->
61+
<dependency>
62+
<groupId>io.springfox</groupId>
63+
<artifactId>springfox-swagger2</artifactId>
64+
<version>2.9.2</version>
65+
</dependency>
66+
<dependency>
67+
<groupId>io.springfox</groupId>
68+
<artifactId>springfox-swagger-ui</artifactId>
69+
<version>2.9.2</version>
70+
</dependency>
71+
5972
</dependencies>
6073

6174
<build>
@@ -64,6 +77,34 @@
6477
<groupId>org.springframework.boot</groupId>
6578
<artifactId>spring-boot-maven-plugin</artifactId>
6679
</plugin>
80+
<plugin>
81+
<groupId>com.github.kongchen</groupId>
82+
<artifactId>swagger-maven-plugin</artifactId>
83+
<configuration>
84+
<apiSources>
85+
<apiSource>
86+
<locations>
87+
<location>com.github.adamzink.springbootmysqldemo.resource</location>
88+
</locations>
89+
<basePath>/api</basePath>
90+
<swaggerDirectory>${project.build.directory}/classes/swagger</swaggerDirectory>
91+
<swaggerFileName>swagger</swaggerFileName>
92+
<info>
93+
<title>Spring Boot MySQL Demo</title>
94+
<version>1.0</version>
95+
</info>
96+
</apiSource>
97+
</apiSources>
98+
</configuration>
99+
<executions>
100+
<execution>
101+
<phase>compile</phase>
102+
<goals>
103+
<goal>generate</goal>
104+
</goals>
105+
</execution>
106+
</executions>
107+
</plugin>
67108
</plugins>
68109
</build>
69110

src/main/java/com/github/adamzink/springbootmysqldemo/JerseyConfiguration.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import org.glassfish.jersey.server.ResourceConfig;
55
import org.springframework.stereotype.Component;
66

7+
import javax.ws.rs.ApplicationPath;
8+
9+
@ApplicationPath("/api")
710
@Component
811
public class JerseyConfiguration extends ResourceConfig {
912

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.github.adamzink.springbootmysqldemo.config;
2+
3+
import org.springframework.context.annotation.Configuration;
4+
import org.springframework.context.annotation.Primary;
5+
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
6+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7+
import springfox.documentation.swagger.web.SwaggerResource;
8+
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
9+
import springfox.documentation.swagger2.annotations.EnableSwagger2;
10+
11+
import java.util.Collections;
12+
import java.util.List;
13+
14+
@Configuration
15+
@EnableSwagger2
16+
@Primary
17+
public class SwaggerConfiguration implements SwaggerResourcesProvider, WebMvcConfigurer {
18+
19+
@Override
20+
public List<SwaggerResource> get() {
21+
SwaggerResource swaggerResource = new SwaggerResource();
22+
swaggerResource.setLocation("/swagger/swagger.json");
23+
swaggerResource.setName("Spring Boot MySQL Demo API");
24+
25+
return Collections.singletonList(swaggerResource);
26+
}
27+
28+
@Override
29+
public void addResourceHandlers(ResourceHandlerRegistry registry) {
30+
registry.addResourceHandler("swagger-ui.html")
31+
.addResourceLocations("classpath:/META-INF/resources/");
32+
33+
registry.addResourceHandler("/swagger/**")
34+
.addResourceLocations("classpath:/swagger/");
35+
}
36+
}

src/main/java/com/github/adamzink/springbootmysqldemo/resource/UserResource.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.github.adamzink.springbootmysqldemo.model.client.User;
44
import com.github.adamzink.springbootmysqldemo.model.client.UserRequest;
55
import com.github.adamzink.springbootmysqldemo.service.UserService;
6+
import io.swagger.annotations.*;
67
import org.springframework.beans.factory.annotation.Autowired;
78
import org.springframework.stereotype.Component;
89

@@ -11,6 +12,7 @@
1112
import java.util.Collection;
1213

1314
@Path("/users")
15+
@Api(value = "User", description = "Resource for getting and modifying Users")
1416
@Component
1517
public class UserResource {
1618

@@ -19,28 +21,48 @@ public class UserResource {
1921

2022
@GET
2123
@Produces(MediaType.APPLICATION_JSON)
24+
@ApiOperation(value = "Get all Users",
25+
response = User.class,
26+
responseContainer = "List")
2227
public Collection<User> getAll() {
2328
return userService.getAll();
2429
}
2530

2631
@POST
2732
@Consumes(MediaType.APPLICATION_JSON)
2833
@Produces(MediaType.APPLICATION_JSON)
29-
public User save(final UserRequest userRequest) {
34+
@ApiOperation(value = "Create a User",
35+
response = User.class)
36+
@ApiResponses(value = {
37+
@ApiResponse(code = 400, message = "Bad request format")})
38+
public User save(
39+
@ApiParam(value = "User to be created", required = true) final UserRequest userRequest) {
3040
return userService.save(userRequest);
3141
}
3242

3343
@PUT
3444
@Path("{id}")
3545
@Consumes(MediaType.APPLICATION_JSON)
3646
@Produces(MediaType.APPLICATION_JSON)
37-
public User update(@PathParam("id") final Long id, final UserRequest userRequest) {
47+
@ApiOperation(value = "Update a User",
48+
response = User.class)
49+
@ApiResponses(value = {
50+
@ApiResponse(code = 400, message = "Bad request format"),
51+
@ApiResponse(code = 404, message = "User not found")})
52+
public User update(
53+
@ApiParam(value = "User id to update", required = true) @PathParam("id") final Long id,
54+
@ApiParam(value = "User details to be updated", required = true) final UserRequest userRequest) {
3855
return userService.update(id, userRequest);
3956
}
4057

4158
@DELETE
4259
@Path("{id}")
43-
public void delete(@PathParam("id") final Long id) {
60+
@ApiOperation(value = "Delete a User")
61+
@ApiResponses(value = {
62+
@ApiResponse(code = 204, message = "User deleted successfully"),
63+
@ApiResponse(code = 404, message = "User not found")})
64+
public void delete(
65+
@ApiParam(value = "User id to delete", required = true) @PathParam("id") final Long id) {
4466
userService.delete(id);
4567
}
4668

src/main/java/com/github/adamzink/springbootmysqldemo/service/UserService.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import org.springframework.stereotype.Service;
1010
import org.springframework.transaction.annotation.Transactional;
1111

12+
import javax.ws.rs.BadRequestException;
13+
import javax.ws.rs.NotFoundException;
1214
import java.util.Collection;
1315
import java.util.Date;
1416

@@ -27,26 +29,38 @@ public Collection<User> getAll() {
2729
}
2830

2931
public User save(final UserRequest userRequest) {
30-
UserModel userModel = userConverter.requestToModel(userRequest);
32+
UserModel userModel = getValidatedRequestToModel(userRequest);
3133

3234
userModel.setAddTs(new Date());
3335

3436
return userConverter.modelToResponse(userRepository.save(userModel));
3537
}
3638

3739
public User update(final Long id, final UserRequest userRequest) {
38-
UserModel fromRequest = userConverter.requestToModel(userRequest);
40+
UserModel toSave = userRepository.findById(id).orElseThrow(NotFoundException::new);
41+
42+
UserModel fromRequest = getValidatedRequestToModel(userRequest);
3943

40-
UserModel toSave = userRepository.getOne(id);
4144
toSave.setFirstName(fromRequest.getFirstName());
4245
toSave.setLastName(fromRequest.getLastName());
4346

4447
return userConverter.modelToResponse(userRepository.save(toSave));
4548
}
4649

4750
public void delete(final Long id) {
51+
userRepository.findById(id).orElseThrow(NotFoundException::new);
4852
userRepository.deleteById(id);
4953
}
5054

55+
private UserModel getValidatedRequestToModel(final UserRequest userRequest) {
56+
UserModel model = userConverter.requestToModel(userRequest);
57+
58+
if (model.getFirstName() == null || model.getLastName() == null) {
59+
throw new BadRequestException();
60+
}
61+
62+
return model;
63+
}
64+
5165
}
5266

src/main/resources/application.properties

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,3 @@ spring.datasource.driver-class-name=com.mysql.jdbc.Driver
66

77
# Flyway properties
88
spring.flyway.locations=classpath:db/mysql/migration
9-
10-
# Path properties
11-
server.servlet.contextPath=/api

0 commit comments

Comments
 (0)