You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+44-52Lines changed: 44 additions & 52 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,13 @@
1
1
2
2
3
-
# Part 1 - Domain Implementation<br>
3
+
# Part 1 - Domain Implementation
4
+
4
5
*_Domain objects_ are the backbone for an application and contain the [business logic](https://en.wikipedia.org/wiki/Business_logic).
5
6
* Create a sub package of `io.zipcoder.tc_spring_poll_application` named `domain`.
6
7
7
8
8
-
-
9
9
## Part 1.1 - Create class `Option`
10
+
10
11
* Create an `Option` class in the `domain` sub-package.
11
12
*`Option` class signature is annotated with `@Entity`
12
13
*`Option` has an `id` instance variable of type `Long`
@@ -25,8 +26,8 @@
25
26
* Create a `getter` and `setter` for each of the respective instance variables.
26
27
27
28
28
-
-
29
29
## Part 1.2 - Create class `Poll`
30
+
30
31
* Create a `Poll` class in the `domain` sub-package.
31
32
*`Poll` class signature is annotated with `@Entity`
32
33
*`Poll` has an `id` instance variable of type `Long`
@@ -48,9 +49,8 @@
48
49
* Create a `getter` and `setter` for each of the respective instance variables.
49
50
50
51
51
-
52
-
-
53
52
## Part 1.3 - Create class `Vote`
53
+
54
54
* Create a `Vote` class in the `domain` sub-package.
55
55
*`Vote` class signature is annotated with `@Entity`
56
56
*`Vote` has an `id` instance variable of type `Long`
@@ -67,55 +67,49 @@
67
67
* Create a `getter` and `setter` for each of the respective instance variables.
68
68
69
69
70
-
71
-
72
-
-
73
-
-
74
70
# Part 2 - Repository Implementation
71
+
75
72
*_Repositories_ or [Data Access Objects (DAO)](https://en.wikipedia.org/wiki/Data_access_object), provide an abstraction for interacting with _datastores_.
76
73
* Typically DAOs include an interface that provides a set of finder methods such as `findById`, `findAll`, for retrieving data, and methods to persist and delete data.
77
74
* It is customary to have one `Repository` per `domain` object.
78
75
* Create a sub-package of `io.zipcoder.tc_spring_poll_application` named `repositories`.
79
76
80
77
81
-
-
82
78
## Part 2.1 - Create interface `OptionRepository`
79
+
83
80
* Create an `OptionRepository` interface in the `repositories` subpackage.
*_Controllers_ provides all of the necessary [endpoints](https://en.wikipedia.org/wiki/Web_API#Endpoints) to access and manipulate respective domain objects.
105
98
* REST resources are identified using URI endpoints.
106
99
* Create a sub package of `io.zipcoder.tc_spring_poll_application` named `controller`.
107
100
108
101
109
-
-
110
102
## Part 3.1 - Create class `PollController`
103
+
111
104
* Create a `PollController` class in the `controller` sub package.
112
105
* `PollController` signature should be `annotated` with `@RestController`
113
106
114
107
*`PollController` has a `pollRepository` instance variable of type `PollRepository`
115
108
* `pollRepository` should be `annotated` with `@Inject`
116
109
117
-
-
110
+
118
111
### Part 3.1.1 - Create `GET` request method
112
+
119
113
* The method definition below supplies a `GET` request on the `/polls` endpoint which provides a collection of all of the polls available in the QuickPolls application. Copy and paste this into your `PollController` class.
120
114
121
115
```java
@@ -132,9 +126,8 @@ public ResponseEntity<Iterable<Poll>> getAllPolls() {
132
126
133
127
134
128
135
-
136
-
-
137
129
### Part 3.1.2 - Testing via Postman
130
+
138
131
* Ensure that the `start-class` tag in your `pom.xml` encapsulates `io.zipcoder.springdemo.QuickPollApplication`
139
132
* Open a command line and navigate to the project's root directory and run this command:
140
133
* `mvn spring-boot:run`
@@ -143,9 +136,8 @@ public ResponseEntity<Iterable<Poll>> getAllPolls() {
143
136
144
137
145
138
146
-
147
-
-
148
139
### Part 3.1.3 - Create `POST` request method
140
+
149
141
* We accomplish the capability to add new polls to the `PollController` by implementing the `POST` verb functionality in a `createPoll` method:
150
142
151
143
```java
@@ -164,9 +156,8 @@ public ResponseEntity<?> createPoll(@RequestBody Poll poll) {
164
156
165
157
166
158
167
-
168
-
-
169
159
### Part 3.1.4 - Modify `createPoll`
160
+
170
161
* Best practice is to convey the URI to the newly created resource using the Location HTTP header via Spring's `ServletUriComponentsBuilder` utility class. This will ensure that the client has some way of knowing the URI of the newly created Poll.
171
162
172
163
```java
@@ -181,9 +172,8 @@ URI newPollUri = ServletUriComponentsBuilder
181
172
182
173
183
174
184
-
185
-
-
186
175
### Part 3.1.5 - Create `GET` request method
176
+
187
177
* The code snippet below enables us to access an individual poll.
188
178
* The _value attribute_ in the `@RequestMapping` takes a URI template `/polls/{pollId}`.
189
179
* The placeholder `{pollId}` along with `@PathVarible` annotation allows Spring to examine the request URI path and extract the `pollId` parameter value.
@@ -198,10 +188,8 @@ public ResponseEntity<?> getPoll(@PathVariable Long pollId) {
198
188
```
199
189
200
190
201
-
202
-
203
-
-
204
191
### Part 3.1.6 - Create `UPDATE` request method
192
+
205
193
* The code snippet below enables us to update a poll.
206
194
207
195
```java
@@ -214,8 +202,6 @@ public ResponseEntity<?> updatePoll(@RequestBody Poll poll, @PathVariable Long p
214
202
```
215
203
216
204
217
-
218
-
-
219
205
### Part 3.1.7 - Create `DELETE` request method.
220
206
221
207
* The code snippet below enables us to delete a poll.
@@ -229,10 +215,8 @@ public ResponseEntity<?> deletePoll(@PathVariable Long pollId) {
229
215
```
230
216
231
217
232
-
233
-
234
-
-
235
218
### Part 3.1.8 - Test
219
+
236
220
* Restart the QuickPoll application.
237
221
* Use Postman to execute a `POST` to `http://localhost:8080/polls/` whose request body is the `JSON` object below.
238
222
* You can modify the request body in Postman by navigating to the `Body` tab, selecting the `raw` radio button, and selecting the `JSON` option from the text format dropdown.
@@ -251,8 +235,8 @@ public ResponseEntity<?> deletePoll(@PathVariable Long pollId) {
251
235
```
252
236
253
237
254
-
-
255
238
## Part 3.2 - Create class `VoteController`
239
+
256
240
* Following the principles used to create `PollController`, we implement the `VoteController` class.
257
241
* Below is the code for the `VoteController` class along with the functionality to create a vote.
258
242
* The `VoteController` uses an injected instance of `VoteRepository` to perform `CRUD` operations on Vote instances.
@@ -277,6 +261,7 @@ public class VoteController {
277
261
```
278
262
279
263
### Part 3.2.1 - Testing `VoteController`
264
+
280
265
* To test the voting capabilities, `POST` a new Vote to the `/polls/1/votes` endpoint with the option object expressed in `JSON` below.
281
266
* On successful request execution, you will see a Location response header with value http://localhost:8080/polls/1/votes/1.
282
267
@@ -287,10 +272,8 @@ public class VoteController {
287
272
```
288
273
289
274
290
-
291
-
292
-
-
293
275
### Part 3.2.2 - Modify `VoteRepository`
276
+
294
277
* The method `findAll` in the `VoteRepository` retrieves all votes in a Database rather than a given poll.
295
278
* To ensure we can get votes for a given poll, we must add the code below to our `VoteRepository`.
* At runtime, Spring Data JPA replaces the `?1` placeholder with the passed-in `pollId` parameter value.
310
293
311
294
312
-
313
-
-
314
295
### Part 3.2.3 - Modify `VoteController`
296
+
315
297
* Create a `getAllVotes` method in the `VoteController`
316
298
317
299
@@ -322,15 +304,16 @@ public Iterable<Vote> getAllVotes(@PathVariable Long pollId) {
322
304
}
323
305
```
324
306
325
-
-
326
-
-
307
+
327
308
# Part 4 - Data Transfer Object (DTO) Implementation
309
+
328
310
* The final piece remaining for us is the implementation of the ComputeResult resource.
329
311
* Because we don’t have any domain objects that can directly help generate this resource representation, we implement two Data Transfer Objects or DTOs—OptionCount and VoteResult
330
312
* Create a sub package of `java` named `dtos`
331
313
332
-
-
314
+
333
315
## Part 4.1 - Create class `OptionCount`
316
+
334
317
* The `OptionCount` DTO contains the `ID` of the option and a count of votes casted for that option.
335
318
336
319
```java
@@ -356,7 +339,9 @@ public class OptionCount {
356
339
}
357
340
```
358
341
342
+
359
343
## Part 4.2 - Create class `VoteResult`
344
+
360
345
* The `VoteResult` DTO contains the total votes cast and a collection of `OptionCount` instances.
361
346
362
347
```java
@@ -385,6 +370,7 @@ public class VoteResult {
385
370
386
371
387
372
## Part 4.3 - Create class `ComputeResultController`
373
+
388
374
* Following the principles used in creating the `PollController` and `VoteController`, we create a new `ComputeResultController` class
389
375
390
376
```java
@@ -411,6 +397,7 @@ public class ComputeResultController {
411
397
412
398
413
399
## Part4.4-Test via Postman
400
+
414
401
*Start/restart the `QuickPoll` application.
415
402
*Using the earlier Postman requests, create a poll and cast votes on its options.
416
403
*Ensure a JSON file with a `status` of `200` is returned by executing a `GET` request of `http://localhost:8080/computeresults?pollId=1` via Postman
@@ -538,24 +525,27 @@ Size.poll.options=Options must be greater than {2} and less than {1}
538
525
```
539
526
540
527
541
-
542
528
# Part 6 - Pagination
529
+
543
530
* To optimize performance, it is important to limit the amount of data returned, especially in the case of a mobile client.
544
531
* REST services have the ability to give clients access large datasets in manageable chunks, by splitting the data into discrete pages or _paging data_.
545
532
* For this lab, we will approach this by implementing the _page number pagination pattern_.
546
533
547
-
-
534
+
548
535
### Get Data From Page
536
+
549
537
* For example, a client wanting a blog post in page 3 of a hypothetical blog service can use a `GET` method resembling the following:
550
538
`http://blog.example.com/posts?page=3`
551
539
552
-
-
540
+
553
541
### Limit Data Retrieved From Page
542
+
554
543
* It is possible for the client to override the default page size by passing in a page-size parameter:
555
544
`http://blog.example.com/posts?page=3&size=20`
556
545
557
-
-
546
+
558
547
### Pagination Data
548
+
559
549
* Pagination-specific information includes
560
550
* total number of records
561
551
* total number of pages
@@ -574,10 +564,11 @@ Size.poll.options=Options must be greater than {2} and less than {1}
574
564
"totalRecords": 90
575
565
}
576
566
```
567
+
577
568
* Read more about REST pagination in Spring by clicking [here](https://dzone.com/articles/rest-pagination-spring).
578
569
579
570
580
-
-
571
+
581
572
## Part 6.1 - Load Dummy Poll Data
582
573
583
574
* Create a `src/main/resource/import.sql` file with _DML statements_ for populating the database upon bootstrap. The `import.sql` should insert at least 15 polls, each with 3 or more options.
@@ -597,8 +588,9 @@ Size.poll.options=Options must be greater than {2} and less than {1}
597
588
* Restart your application.
598
589
* Use Postman to ensure database is populated by `import.sql`.
599
590
600
-
-
591
+
601
592
## Part 6.2 - Spring's Built-in Pagination
593
+
602
594
*Make use of Spring's built-in page number pagination support by researching `org.springframework.data.repository.PagingAndSortingRepository`.
603
595
* Modify respective `Controller` methods to handle `Pageable` arguments.
604
596
* Send a `GET` request to `http://localhost:8080/polls?page=0&size=2` via Postman.
0 commit comments