Skip to content

Commit 605f40c

Browse files
committed
learn rest-api ch03
1 parent b2746da commit 605f40c

File tree

9 files changed

+201
-7
lines changed

9 files changed

+201
-7
lines changed

Diff for: book/rest-api-demo/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
<dependency>
7575
<groupId>com.h2database</groupId>
7676
<artifactId>h2</artifactId>
77-
<!--<scope>test</scope>-->
77+
<scope>test</scope>
7878
</dependency>
7979

8080
<!-- model mapper -->

Diff for: book/rest-api-demo/scripts.md

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Scripts
2+
3+
Here, I memo scripts that I have used during development.
4+
5+
## Postgres
6+
7+
### Run Postgres Container
8+
9+
```
10+
docker run --name ndb -p 5432:5432 -e POSTGRES_PASSWORD=pass -d postgres
11+
12+
```
13+
14+
This cmdlet will create Postgres instance so that you can connect to a database with:
15+
* database: postgres
16+
* username: postgres
17+
* password: pass
18+
* post: 5432
19+
20+
### Getting into the Postgres container
21+
22+
```
23+
docker exec -i -t ndb bash
24+
```
25+
26+
Then you will see the containers bash as a root user.
27+
28+
### Connect to a database
29+
30+
```
31+
psql -d postgres -U postgres
32+
```
33+
34+
### Query Databases
35+
36+
```
37+
\l
38+
```
39+
40+
### Query Tables
41+
42+
```
43+
\dt
44+
```
45+
46+
### Quit
47+
48+
```
49+
\q
50+
```
51+
52+
## application.properties
53+
54+
### Datasource
55+
56+
```
57+
spring.datasource.username=postgres
58+
spring.datasource.password=pass
59+
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
60+
spring.datasource.driver-class-name=org.postgresql.Driver
61+
```
62+
63+
### Hibernate
64+
65+
```
66+
spring.jpa.hibernate.ddl-auto=create-drop
67+
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
68+
spring.jpa.properties.hibernate.format_sql=true
69+
70+
logging.level.org.hibernate.SQL=DEBUG
71+
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
72+
```
73+
74+
### Test Database
75+
76+
```
77+
spring.datasource.username=sa
78+
spring.datasource.password=
79+
spring.datasource.url=jdbc:h2:mem:testdb
80+
spring.datasource.driver-class-name=org.h2.Driver
81+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package demo.common;
2+
3+
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
4+
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
5+
6+
import demo.index.IndexController;
7+
import org.springframework.hateoas.Link;
8+
import org.springframework.hateoas.Resource;
9+
import org.springframework.validation.Errors;
10+
11+
/**
12+
* https://github.com/keesun/study/tree/master/rest-api-with-spring
13+
*/
14+
public class ErrorsResource extends Resource<Errors> {
15+
16+
public ErrorsResource(Errors content, Link... links) {
17+
super(content, links);
18+
19+
add(linkTo(methodOn(IndexController.class).index()).withRel("index"));
20+
}
21+
}

Diff for: book/rest-api-demo/src/main/java/demo/events/EventController.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
44

5+
import demo.common.ErrorsResource;
56
import java.net.URI;
67
import javax.validation.Valid;
78
import org.modelmapper.ModelMapper;
@@ -38,12 +39,12 @@ public EventController(EventRepository eventRepository, ModelMapper modelMapper,
3839
@PostMapping
3940
public ResponseEntity createEvent(@RequestBody @Valid EventDto eventDto, Errors errors) {
4041
if (errors.hasErrors()) {
41-
return ResponseEntity.badRequest().body(errors);
42+
return badRequest(errors);
4243
}
4344

4445
eventValidator.validate(eventDto, errors);
4546
if (errors.hasErrors()) {
46-
return ResponseEntity.badRequest().body(errors);
47+
return badRequest(errors);
4748
}
4849

4950
Event event = modelMapper.map(eventDto, Event.class);
@@ -59,4 +60,8 @@ public ResponseEntity createEvent(@RequestBody @Valid EventDto eventDto, Errors
5960

6061
return ResponseEntity.created(createdUri).body(eventResource);
6162
}
63+
64+
private ResponseEntity badRequest(Errors errors) {
65+
return ResponseEntity.badRequest().body(new ErrorsResource(errors));
66+
}
6267
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package demo.index;
2+
3+
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
4+
5+
import demo.events.EventController;
6+
import org.springframework.hateoas.ResourceSupport;
7+
import org.springframework.web.bind.annotation.GetMapping;
8+
import org.springframework.web.bind.annotation.RestController;
9+
10+
/**
11+
* https://github.com/keesun/study/tree/master/rest-api-with-spring
12+
*/
13+
@RestController
14+
public class IndexController {
15+
16+
@GetMapping("/api")
17+
public ResourceSupport index() {
18+
ResourceSupport index = new ResourceSupport();
19+
index.add(linkTo(EventController.class).withRel("events"));
20+
return index;
21+
}
22+
}
+15-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
1-
spring.jackson.deserialization.fail-on-unknown-properties=true
1+
spring.jackson.deserialization.fail-on-unknown-properties=true
2+
3+
# Datasource
4+
spring.datasource.username=postgres
5+
spring.datasource.password=pass
6+
spring.datasource.url=jdbc:postgresql://192.168.79.130:5432/postgres
7+
spring.datasource.driver-class-name=org.postgresql.Driver
8+
9+
# Hibernate
10+
spring.jpa.hibernate.ddl-auto=create-drop
11+
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
12+
spring.jpa.properties.hibernate.format_sql=true
13+
14+
logging.level.org.hibernate.SQL=DEBUG
15+
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

Diff for: book/rest-api-demo/src/test/java/demo/events/EventControllerTests.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.hateoas.MediaTypes;
3131
import org.springframework.http.HttpHeaders;
3232
import org.springframework.http.MediaType;
33+
import org.springframework.test.context.ActiveProfiles;
3334
import org.springframework.test.context.junit4.SpringRunner;
3435
import org.springframework.test.web.servlet.MockMvc;
3536

@@ -43,6 +44,7 @@
4344
@Import({
4445
RestDocsConfiguration.class
4546
})
47+
@ActiveProfiles("test")
4648
public class EventControllerTests {
4749

4850
@Autowired
@@ -197,8 +199,9 @@ public void createEvent_Bad_Request_Wrong_Input() throws Exception {
197199
.content(objectMapper.writeValueAsString(eventDto)))
198200
.andDo(print())
199201
.andExpect(status().isBadRequest())
200-
.andExpect(jsonPath("$[0].objectName").exists())
201-
.andExpect(jsonPath("$[0].defaultMessage").exists())
202-
.andExpect(jsonPath("$[0].code").exists());
202+
.andExpect(jsonPath("content[0].objectName").exists())
203+
.andExpect(jsonPath("content[0].defaultMessage").exists())
204+
.andExpect(jsonPath("content[0].code").exists())
205+
.andExpect(jsonPath("_links.index").exists());
203206
}
204207
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package demo.index;
2+
3+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
4+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
5+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
6+
7+
import demo.common.RestDocsConfiguration;
8+
import org.junit.Test;
9+
import org.junit.runner.RunWith;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
12+
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
13+
import org.springframework.boot.test.context.SpringBootTest;
14+
import org.springframework.context.annotation.Import;
15+
import org.springframework.test.context.ActiveProfiles;
16+
import org.springframework.test.context.junit4.SpringRunner;
17+
import org.springframework.test.web.servlet.MockMvc;
18+
19+
/**
20+
* https://github.com/keesun/study/tree/master/rest-api-with-spring
21+
*/
22+
@RunWith(SpringRunner.class)
23+
@SpringBootTest
24+
@AutoConfigureMockMvc
25+
@AutoConfigureRestDocs
26+
@Import({
27+
RestDocsConfiguration.class
28+
})
29+
@ActiveProfiles("test")
30+
public class IndexControllerTest {
31+
32+
@Autowired
33+
MockMvc mockMvc;
34+
35+
@Test
36+
public void index() throws Exception {
37+
mockMvc.perform(get("/api/"))
38+
.andExpect(status().isOk())
39+
.andExpect(jsonPath("_links.events").exists());
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
spring.datasource.username=sa
2+
spring.datasource.password=
3+
spring.datasource.url=jdbc:h2:mem:testdb
4+
spring.datasource.driver-class-name=org.h2.Driver
5+
6+
spring.datasource.hikari.jdbc-url=jdbc:h2:mem:testdb
7+
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect

0 commit comments

Comments
 (0)