Skip to content

Commit d3fd236

Browse files
author
springdoc
committed
project update
1 parent 87d5358 commit d3fd236

File tree

8 files changed

+520
-1
lines changed

8 files changed

+520
-1
lines changed

springdoc-openapi-data-rest/pom.xml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,25 @@
3030
<version>${project.version}</version>
3131
<scope>test</scope>
3232
</dependency>
33+
<dependency>
34+
<groupId>org.springframework.boot</groupId>
35+
<artifactId>spring-boot-starter-hateoas</artifactId>
36+
<scope>test</scope>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.springframework.boot</groupId>
40+
<artifactId>spring-boot-starter-data-jpa</artifactId>
41+
<scope>test</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>com.h2database</groupId>
45+
<artifactId>h2</artifactId>
46+
<scope>test</scope>
47+
</dependency>
48+
<dependency>
49+
<groupId>org.projectlombok</groupId>
50+
<artifactId>lombok</artifactId>
51+
<scope>test</scope>
52+
</dependency>
3353
</dependencies>
34-
3554
</project>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package test.org.springdoc.api.app2;
17+
18+
import org.springframework.boot.CommandLineRunner;
19+
import org.springframework.context.annotation.Bean;
20+
import org.springframework.stereotype.Component;
21+
22+
/**
23+
* Pre-load some data using a Spring Boot {@link CommandLineRunner}.
24+
*
25+
* @author Greg Turnquist
26+
*/
27+
@Component
28+
class DatabaseLoader {
29+
30+
/**
31+
* Use Spring to inject a {@link EmployeeRepository} that can then load data. Since this will run only after the app
32+
* is operational, the database will be up.
33+
*
34+
* @param repository
35+
*/
36+
@Bean
37+
CommandLineRunner init(EmployeeRepository repository) {
38+
39+
return args -> {
40+
repository.save(new Employee("Frodo", "Baggins", "ring bearer"));
41+
repository.save(new Employee("Bilbo", "Baggins", "burglar"));
42+
};
43+
}
44+
45+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package test.org.springdoc.api.app2;
17+
18+
import lombok.AccessLevel;
19+
import lombok.AllArgsConstructor;
20+
import lombok.Data;
21+
import lombok.NoArgsConstructor;
22+
23+
import javax.persistence.Entity;
24+
import javax.persistence.GeneratedValue;
25+
import javax.persistence.Id;
26+
27+
/**
28+
* Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} -
29+
* Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class
30+
* for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA
31+
* {@code @AllArgsConstructor} - Create a constructor with all args to support testing
32+
* {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes.
33+
* This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows
34+
* things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without
35+
* adjustment.
36+
*
37+
* @author Greg Turnquist
38+
*/
39+
@Data
40+
@Entity
41+
@NoArgsConstructor(access = AccessLevel.PRIVATE)
42+
@AllArgsConstructor
43+
class Employee {
44+
45+
@Id @GeneratedValue private Long id;
46+
private String firstName;
47+
private String lastName;
48+
private String role;
49+
50+
/**
51+
* Useful constructor when id is not yet known.
52+
*
53+
* @param firstName
54+
* @param lastName
55+
* @param role
56+
*/
57+
Employee(String firstName, String lastName, String role) {
58+
59+
this.firstName = firstName;
60+
this.lastName = lastName;
61+
this.role = role;
62+
}
63+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package test.org.springdoc.api.app2;
17+
18+
import org.springframework.hateoas.CollectionModel;
19+
import org.springframework.hateoas.EntityModel;
20+
import org.springframework.hateoas.IanaLinkRelations;
21+
import org.springframework.hateoas.Link;
22+
import org.springframework.http.ResponseEntity;
23+
import org.springframework.web.bind.annotation.*;
24+
25+
import java.net.URI;
26+
import java.net.URISyntaxException;
27+
import java.util.List;
28+
import java.util.stream.Collectors;
29+
import java.util.stream.StreamSupport;
30+
31+
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
32+
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
33+
34+
/**
35+
* Spring Web {@link RestController} used to generate a REST API.
36+
*
37+
* @author Greg Turnquist
38+
*/
39+
@RestController
40+
class EmployeeController {
41+
42+
private final EmployeeRepository repository;
43+
44+
EmployeeController(EmployeeRepository repository) {
45+
this.repository = repository;
46+
}
47+
48+
/**
49+
* Look up all employees, and transform them into a REST collection resource. Then return them through Spring Web's
50+
* {@link ResponseEntity} fluent API.
51+
*/
52+
@GetMapping("/employees")
53+
ResponseEntity<CollectionModel<EntityModel<Employee>>> findAll() {
54+
55+
List<EntityModel<Employee>> employees = StreamSupport.stream(repository.findAll().spliterator(), false)
56+
.map(employee -> new EntityModel<>(employee, //
57+
linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel(), //
58+
linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) //
59+
.collect(Collectors.toList());
60+
61+
return ResponseEntity.ok( //
62+
new CollectionModel<>(employees, //
63+
linkTo(methodOn(EmployeeController.class).findAll()).withSelfRel()));
64+
}
65+
66+
@PostMapping("/employees")
67+
ResponseEntity<EntityModel<Employee>> newEmployee(@RequestBody Employee employee) {
68+
69+
try {
70+
Employee savedEmployee = repository.save(employee);
71+
72+
EntityModel<Employee> employeeResource = new EntityModel<>(savedEmployee, //
73+
linkTo(methodOn(EmployeeController.class).findOne(savedEmployee.getId())).withSelfRel());
74+
75+
return ResponseEntity //
76+
.created(new URI(employeeResource.getRequiredLink(IanaLinkRelations.SELF).getHref())) //
77+
.body(employeeResource);
78+
} catch (URISyntaxException e) {
79+
return ResponseEntity.badRequest().body(null);
80+
}
81+
}
82+
83+
/**
84+
* Look up a single {@link Employee} and transform it into a REST resource. Then return it through Spring Web's
85+
* {@link ResponseEntity} fluent API.
86+
*
87+
* @param id
88+
*/
89+
@GetMapping("/employees/{id}")
90+
ResponseEntity<EntityModel<Employee>> findOne(@PathVariable long id) {
91+
92+
return repository.findById(id) //
93+
.map(employee -> new EntityModel<>(employee, //
94+
linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel(), //
95+
linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) //
96+
.map(ResponseEntity::ok) //
97+
.orElse(ResponseEntity.notFound().build());
98+
}
99+
100+
/**
101+
* Update existing employee then return a Location header.
102+
*
103+
* @param employee
104+
* @param id
105+
* @return
106+
*/
107+
@PutMapping("/employees/{id}")
108+
ResponseEntity<Void> updateEmployee(@RequestBody Employee employee, @PathVariable long id) throws URISyntaxException {
109+
110+
Employee employeeToUpdate = employee;
111+
employeeToUpdate.setId(id);
112+
repository.save(employeeToUpdate);
113+
114+
Link newlyCreatedLink = linkTo(methodOn(EmployeeController.class).findOne(id)).withSelfRel();
115+
116+
return ResponseEntity.noContent().location(new URI(newlyCreatedLink.getHref())).build();
117+
118+
}
119+
120+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package test.org.springdoc.api.app2;
17+
18+
import org.springframework.data.repository.CrudRepository;
19+
20+
/**
21+
* A simple Spring Data {@link CrudRepository} for storing {@link Employee}s.
22+
*
23+
* @author Greg Turnquist
24+
*/
25+
interface EmployeeRepository extends CrudRepository<Employee, Long> {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package test.org.springdoc.api.app2;
2+
3+
import test.org.springdoc.api.AbstractSpringDocTest;
4+
5+
public class SpringDocApp2Test extends AbstractSpringDocTest {
6+
7+
8+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package test.org.springdoc.api.app2;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.hateoas.server.core.EvoInflectorLinkRelationProvider;
7+
8+
@SpringBootApplication
9+
public class SpringDocTestApp {
10+
11+
public static void main(String[] args) {
12+
SpringApplication.run(SpringDocTestApp.class, args);
13+
}
14+
15+
@Bean
16+
EvoInflectorLinkRelationProvider relProvider() {
17+
return new EvoInflectorLinkRelationProvider();
18+
}
19+
20+
}

0 commit comments

Comments
 (0)