From 85176f2bf828946be03097c3b4348b5da737be3c Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 20 Jul 2017 23:38:23 -0400 Subject: [PATCH 1/9] added file `import.sql` to `src/main/resources` --- src/main/resources/import.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/import.sql diff --git a/src/main/resources/import.sql b/src/main/resources/import.sql new file mode 100644 index 0000000..e69de29 From fc4dfcb4f1acdf650ed80e0e208cf8ea07f88b51 Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 20 Jul 2017 23:49:12 -0400 Subject: [PATCH 2/9] added file `import.sql` to `src/main/resources` --- src/main/resources/import.sql | 113 ++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/src/main/resources/import.sql b/src/main/resources/import.sql index e69de29..7772221 100644 --- a/src/main/resources/import.sql +++ b/src/main/resources/import.sql @@ -0,0 +1,113 @@ +insert into poll (poll_id, question) values (1, 'What is your favorite color?'); +insert into option (option_id, option_value, poll_id) values (1, 'Red', 1); +insert into option (option_id, option_value, poll_id) values (2, 'Black', 1); +insert into option (option_id, option_value, poll_id) values (3, 'Blue', 1); +insert into option (option_id, option_value, poll_id) values (4, 'White', 1); + +insert into poll (poll_id, question) values (2, 'What is your favorite Credit Card?'); +insert into option (option_id, option_value, poll_id) values (5, 'American Express', 2); +insert into option (option_id, option_value, poll_id) values (6, 'Visa', 2); +insert into option (option_id, option_value, poll_id) values (7, 'Master Card', 2); +insert into option (option_id, option_value, poll_id) values (8, 'Discover', 2); + +insert into poll (poll_id, question) values (3, 'What is your favorite Sport?'); +insert into option (option_id, option_value, poll_id) values (9, 'Football', 3); +insert into option (option_id, option_value, poll_id) values (10, 'Basketball', 3); +insert into option (option_id, option_value, poll_id) values (11, 'Cricket', 3); +insert into option (option_id, option_value, poll_id) values (12, 'Baseball', 3); + +insert into poll (poll_id, question) values (4, 'How long have you used spring framework?'); +insert into option (option_id, option_value, poll_id) values (13, 'One Year', 4); +insert into option (option_id, option_value, poll_id) values (14, 'Two Years', 4); +insert into option (option_id, option_value, poll_id) values (15, 'Three Years', 4); +insert into option (option_id, option_value, poll_id) values (16, 'Four Years', 4); + +insert into poll (poll_id, question) values (5, 'How do you rate overall satisfaction with Apress Books?'); +insert into option (option_id, option_value, poll_id) values (17, 'Very Satisfied', 5); +insert into option (option_id, option_value, poll_id) values (18, 'Somewhat Satisfied', 5); +insert into option (option_id, option_value, poll_id) values (19, 'Neutral', 5); +insert into option (option_id, option_value, poll_id) values (20, 'Somewhat Dissatisfied', 5); +insert into option (option_id, option_value, poll_id) values (21, 'Dissatisfied', 5); + +insert into poll (poll_id, question) values (6, 'What is your favorite Disney Movie?'); +insert into option (option_id, option_value, poll_id) values (22, 'Cars', 6); +insert into option (option_id, option_value, poll_id) values (23, 'Toy Story', 6); + +insert into poll (poll_id, question) values (7, 'Who is going to win 2016 elections in United States ?'); +insert into option (option_id, option_value, poll_id) values (24, 'Democrat', 7); +insert into option (option_id, option_value, poll_id) values (25, 'Republican', 7); + +insert into poll (poll_id, question) values (8, 'Who is going to host next Olympics?'); +insert into option (option_id, option_value, poll_id) values (26, 'Brazil', 8); +insert into option (option_id, option_value, poll_id) values (27, 'USA', 8); +insert into option (option_id, option_value, poll_id) values (28, 'UK', 8); + +insert into poll (poll_id, question) values (9, 'What is the rhinos horn made of?'); +insert into option (option_id, option_value, poll_id) values (29, 'Bone', 9); +insert into option (option_id, option_value, poll_id) values (30, 'Hair', 9); +insert into option (option_id, option_value, poll_id) values (31, 'Skin', 9); + +insert into poll (poll_id, question) values (10, 'Entomology is the science that studies?'); +insert into option (option_id, option_value, poll_id) values (32, 'insects', 10); +insert into option (option_id, option_value, poll_id) values (33, 'Formation of Rocks', 10); +insert into option (option_id, option_value, poll_id) values (34, 'Birds', 10); +insert into option (option_id, option_value, poll_id) values (35, 'Light', 10); + +insert into poll (poll_id, question) values (11, 'How many toes does a dog have?'); +insert into option (option_id, option_value, poll_id) values (36, '5', 11); +insert into option (option_id, option_value, poll_id) values (37, '10', 11); +insert into option (option_id, option_value, poll_id) values (38, '12', 11); +insert into option (option_id, option_value, poll_id) values (39, '8', 11); + +insert into poll (poll_id, question) values (12, 'Which is the smallest ocean in the world?'); +insert into option (option_id, option_value, poll_id) values (40, 'Arctic Ocean', 12); +insert into option (option_id, option_value, poll_id) values (41, 'Indian Ocean', 12); +insert into option (option_id, option_value, poll_id) values (42, 'Pacific Ocean', 12); +insert into option (option_id, option_value, poll_id) values (43, 'Atlantic Ocean', 12); + +insert into poll (poll_id, question) values (13, 'What is the biggest State in the US?'); +insert into option (option_id, option_value, poll_id) values (44, 'Texas', 13); +insert into option (option_id, option_value, poll_id) values (45, 'California', 13); +insert into option (option_id, option_value, poll_id) values (46, 'Florida', 13); +insert into option (option_id, option_value, poll_id) values (47, 'Alaska', 13); + +insert into poll (poll_id, question) values (14, 'Famous Online Shopping Sites?'); +insert into option (option_id, option_value, poll_id) values (48, 'Amazon', 14); +insert into option (option_id, option_value, poll_id) values (49, 'Overstock', 14); +insert into option (option_id, option_value, poll_id) values (50, 'ebay', 14); + +insert into poll (poll_id, question) values (15, 'How many keys are on a standard piano?'); +insert into option (option_id, option_value, poll_id) values (51, '66', 15); +insert into option (option_id, option_value, poll_id) values (52, '44', 15); +insert into option (option_id, option_value, poll_id) values (53, '88', 15); +insert into option (option_id, option_value, poll_id) values (54, '122', 15); + +insert into poll (poll_id, question) values (16, 'Which country gave America the Statue of Liberty?'); +insert into option (option_id, option_value, poll_id) values (55, 'Canada', 16); +insert into option (option_id, option_value, poll_id) values (56, 'France', 16); +insert into option (option_id, option_value, poll_id) values (57, 'Germany', 16); +insert into option (option_id, option_value, poll_id) values (58, 'England', 16); + +insert into poll (poll_id, question) values (17, 'Best Christmas Gift?'); +insert into option (option_id, option_value, poll_id) values (59, 'Smartphone', 17); +insert into option (option_id, option_value, poll_id) values (60, 'Car', 17); +insert into option (option_id, option_value, poll_id) values (61, 'House', 17); +insert into option (option_id, option_value, poll_id) values (62, 'World Trip', 17); + +insert into poll (poll_id, question) values (18, 'Favorite Vaccation Place?'); +insert into option (option_id, option_value, poll_id) values (63, 'Paris', 18); +insert into option (option_id, option_value, poll_id) values (64, 'Hawaii', 18); +insert into option (option_id, option_value, poll_id) values (65, 'Sydney', 18); +insert into option (option_id, option_value, poll_id) values (66, 'Tokyo', 18); + +insert into poll (poll_id, question) values (19, 'Philology is the study of?'); +insert into option (option_id, option_value, poll_id) values (67, 'Bones', 19); +insert into option (option_id, option_value, poll_id) values (68, 'Muscles', 19); +insert into option (option_id, option_value, poll_id) values (69, 'Architecture', 19); +insert into option (option_id, option_value, poll_id) values (70, 'Languages', 19); + +insert into poll (poll_id, question) values (20, 'How many rings are on the Olympic flag?'); +insert into option (option_id, option_value, poll_id) values (71, '6', 20); +insert into option (option_id, option_value, poll_id) values (72, '8', 20); +insert into option (option_id, option_value, poll_id) values (73, '5', 20); +insert into option (option_id, option_value, poll_id) values (74, '4', 20); \ No newline at end of file From 79d43354d3c5447b10969aee587dc2c7bc96fa0c Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 21 Jul 2017 01:49:04 -0400 Subject: [PATCH 3/9] updated resources --- src/main/resources/import.sql | 113 +--------------------------------- 1 file changed, 1 insertion(+), 112 deletions(-) diff --git a/src/main/resources/import.sql b/src/main/resources/import.sql index 7772221..c472f11 100644 --- a/src/main/resources/import.sql +++ b/src/main/resources/import.sql @@ -1,113 +1,2 @@ insert into poll (poll_id, question) values (1, 'What is your favorite color?'); -insert into option (option_id, option_value, poll_id) values (1, 'Red', 1); -insert into option (option_id, option_value, poll_id) values (2, 'Black', 1); -insert into option (option_id, option_value, poll_id) values (3, 'Blue', 1); -insert into option (option_id, option_value, poll_id) values (4, 'White', 1); - -insert into poll (poll_id, question) values (2, 'What is your favorite Credit Card?'); -insert into option (option_id, option_value, poll_id) values (5, 'American Express', 2); -insert into option (option_id, option_value, poll_id) values (6, 'Visa', 2); -insert into option (option_id, option_value, poll_id) values (7, 'Master Card', 2); -insert into option (option_id, option_value, poll_id) values (8, 'Discover', 2); - -insert into poll (poll_id, question) values (3, 'What is your favorite Sport?'); -insert into option (option_id, option_value, poll_id) values (9, 'Football', 3); -insert into option (option_id, option_value, poll_id) values (10, 'Basketball', 3); -insert into option (option_id, option_value, poll_id) values (11, 'Cricket', 3); -insert into option (option_id, option_value, poll_id) values (12, 'Baseball', 3); - -insert into poll (poll_id, question) values (4, 'How long have you used spring framework?'); -insert into option (option_id, option_value, poll_id) values (13, 'One Year', 4); -insert into option (option_id, option_value, poll_id) values (14, 'Two Years', 4); -insert into option (option_id, option_value, poll_id) values (15, 'Three Years', 4); -insert into option (option_id, option_value, poll_id) values (16, 'Four Years', 4); - -insert into poll (poll_id, question) values (5, 'How do you rate overall satisfaction with Apress Books?'); -insert into option (option_id, option_value, poll_id) values (17, 'Very Satisfied', 5); -insert into option (option_id, option_value, poll_id) values (18, 'Somewhat Satisfied', 5); -insert into option (option_id, option_value, poll_id) values (19, 'Neutral', 5); -insert into option (option_id, option_value, poll_id) values (20, 'Somewhat Dissatisfied', 5); -insert into option (option_id, option_value, poll_id) values (21, 'Dissatisfied', 5); - -insert into poll (poll_id, question) values (6, 'What is your favorite Disney Movie?'); -insert into option (option_id, option_value, poll_id) values (22, 'Cars', 6); -insert into option (option_id, option_value, poll_id) values (23, 'Toy Story', 6); - -insert into poll (poll_id, question) values (7, 'Who is going to win 2016 elections in United States ?'); -insert into option (option_id, option_value, poll_id) values (24, 'Democrat', 7); -insert into option (option_id, option_value, poll_id) values (25, 'Republican', 7); - -insert into poll (poll_id, question) values (8, 'Who is going to host next Olympics?'); -insert into option (option_id, option_value, poll_id) values (26, 'Brazil', 8); -insert into option (option_id, option_value, poll_id) values (27, 'USA', 8); -insert into option (option_id, option_value, poll_id) values (28, 'UK', 8); - -insert into poll (poll_id, question) values (9, 'What is the rhinos horn made of?'); -insert into option (option_id, option_value, poll_id) values (29, 'Bone', 9); -insert into option (option_id, option_value, poll_id) values (30, 'Hair', 9); -insert into option (option_id, option_value, poll_id) values (31, 'Skin', 9); - -insert into poll (poll_id, question) values (10, 'Entomology is the science that studies?'); -insert into option (option_id, option_value, poll_id) values (32, 'insects', 10); -insert into option (option_id, option_value, poll_id) values (33, 'Formation of Rocks', 10); -insert into option (option_id, option_value, poll_id) values (34, 'Birds', 10); -insert into option (option_id, option_value, poll_id) values (35, 'Light', 10); - -insert into poll (poll_id, question) values (11, 'How many toes does a dog have?'); -insert into option (option_id, option_value, poll_id) values (36, '5', 11); -insert into option (option_id, option_value, poll_id) values (37, '10', 11); -insert into option (option_id, option_value, poll_id) values (38, '12', 11); -insert into option (option_id, option_value, poll_id) values (39, '8', 11); - -insert into poll (poll_id, question) values (12, 'Which is the smallest ocean in the world?'); -insert into option (option_id, option_value, poll_id) values (40, 'Arctic Ocean', 12); -insert into option (option_id, option_value, poll_id) values (41, 'Indian Ocean', 12); -insert into option (option_id, option_value, poll_id) values (42, 'Pacific Ocean', 12); -insert into option (option_id, option_value, poll_id) values (43, 'Atlantic Ocean', 12); - -insert into poll (poll_id, question) values (13, 'What is the biggest State in the US?'); -insert into option (option_id, option_value, poll_id) values (44, 'Texas', 13); -insert into option (option_id, option_value, poll_id) values (45, 'California', 13); -insert into option (option_id, option_value, poll_id) values (46, 'Florida', 13); -insert into option (option_id, option_value, poll_id) values (47, 'Alaska', 13); - -insert into poll (poll_id, question) values (14, 'Famous Online Shopping Sites?'); -insert into option (option_id, option_value, poll_id) values (48, 'Amazon', 14); -insert into option (option_id, option_value, poll_id) values (49, 'Overstock', 14); -insert into option (option_id, option_value, poll_id) values (50, 'ebay', 14); - -insert into poll (poll_id, question) values (15, 'How many keys are on a standard piano?'); -insert into option (option_id, option_value, poll_id) values (51, '66', 15); -insert into option (option_id, option_value, poll_id) values (52, '44', 15); -insert into option (option_id, option_value, poll_id) values (53, '88', 15); -insert into option (option_id, option_value, poll_id) values (54, '122', 15); - -insert into poll (poll_id, question) values (16, 'Which country gave America the Statue of Liberty?'); -insert into option (option_id, option_value, poll_id) values (55, 'Canada', 16); -insert into option (option_id, option_value, poll_id) values (56, 'France', 16); -insert into option (option_id, option_value, poll_id) values (57, 'Germany', 16); -insert into option (option_id, option_value, poll_id) values (58, 'England', 16); - -insert into poll (poll_id, question) values (17, 'Best Christmas Gift?'); -insert into option (option_id, option_value, poll_id) values (59, 'Smartphone', 17); -insert into option (option_id, option_value, poll_id) values (60, 'Car', 17); -insert into option (option_id, option_value, poll_id) values (61, 'House', 17); -insert into option (option_id, option_value, poll_id) values (62, 'World Trip', 17); - -insert into poll (poll_id, question) values (18, 'Favorite Vaccation Place?'); -insert into option (option_id, option_value, poll_id) values (63, 'Paris', 18); -insert into option (option_id, option_value, poll_id) values (64, 'Hawaii', 18); -insert into option (option_id, option_value, poll_id) values (65, 'Sydney', 18); -insert into option (option_id, option_value, poll_id) values (66, 'Tokyo', 18); - -insert into poll (poll_id, question) values (19, 'Philology is the study of?'); -insert into option (option_id, option_value, poll_id) values (67, 'Bones', 19); -insert into option (option_id, option_value, poll_id) values (68, 'Muscles', 19); -insert into option (option_id, option_value, poll_id) values (69, 'Architecture', 19); -insert into option (option_id, option_value, poll_id) values (70, 'Languages', 19); - -insert into poll (poll_id, question) values (20, 'How many rings are on the Olympic flag?'); -insert into option (option_id, option_value, poll_id) values (71, '6', 20); -insert into option (option_id, option_value, poll_id) values (72, '8', 20); -insert into option (option_id, option_value, poll_id) values (73, '5', 20); -insert into option (option_id, option_value, poll_id) values (74, '4', 20); \ No newline at end of file +insert into option (option_id, option_value, poll_id) values (1, 'Red', 1); \ No newline at end of file From df9ed504fd782b6122b08aaa4177574d7d32e07e Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 21 Jul 2017 01:50:50 -0400 Subject: [PATCH 4/9] updated `README.md` --- README.md | 459 ++++++------------------------------------------------ 1 file changed, 51 insertions(+), 408 deletions(-) diff --git a/README.md b/README.md index fac7f43..0329172 100644 --- a/README.md +++ b/README.md @@ -1,423 +1,66 @@ - - -# Part 1 - Domain Implementation
-* _Domain objects_ are the backbone for an application and contain the [business logic](https://en.wikipedia.org/wiki/Business_logic). -* Create a sub package of `io.zipcoder.tc_spring_poll_application` named `domain`. - - -- -# Part 1.1 - Create class `Option` -* Create an `Option` class in the `domain` sub-package. -* `Option` class signature is annotated with `@Entity` -* `Option` has an `id` instance variable of type `Long` - * `id` should be `annotated` with - * `@Id` - * denotes primary key of this entity - * `@GeneratedValue` - * configures the way of increment of the specified `column(field)` - * `@Column(name = "OPTION_ID")` - * specifies mapped column for a persistent property or field - -* `Option` has a `value` instance variable of type `String` - * `value` should be `annotated` with - * `@Column(name = "OPTION_VALUE")` - -* Create a `getter` and `setter` for each of the respective instance variables. - - -- -# Part 1.2 - Create class `Poll` -* Create a `Poll` class in the `domain` sub-package. -* `Poll` class signature is annotated with `@Entity` -* `Poll` has an `id` instance variable of type `Long` - * `id` should be `annotated` with - * `@Id` - * `@GeneratedValue` - * `Column(name = "POLL_ID")` - -* `Poll` has a `question` instance variable of type `String` - * `question` should be `annotated` with - * `@Column(name = "QUESTION")` - -* `Poll` has an `options` instance variable of type `Set` of `Option` - * `options` should be `annotated` with - * `@OneToMany(cascade = CascadeType.ALL)` - * `@JoinColumn(name = "POLL_ID")` - * `@OrderBy` - -* Create a `getter` and `setter` for each of the respective instance variables. - - - -- -# Part 1.3 - Create class `Vote` -* Create a `Vote` class in the `domain` sub-package. -* `Vote` class signature is annotated with `@Entity` -* `Vote` has an `id` instance variable of type `Long` - * `id` should be `annotated` with - * `@Id` - * `@GeneratedValue` - * `Column(name = "VOTE_ID")` - -* `Vote` has a `option` instance variable of type `Option` - * `option` should be `annotated` with - * `@ManyToOne` - * `@JoinColumn(name = "OPTION_ID")` - -* Create a `getter` and `setter` for each of the respective instance variables. - - - - -- -- -# Part 2 - Repository Implementation -* _Repositories_ or [Data Access Objects (DAO)](https://en.wikipedia.org/wiki/Data_access_object), provide an abstraction for interacting with _datastores_. -* 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. -* It is customary to have one `Repository` per `domain` object. -* Create a sub-package of `io.zipcoder.tc_spring_poll_application` named `repositories`. - - -- -# Part 2.1 - Create interface `OptionRepository` -* Create an `OptionRepository` interface in the `repositories` subpackage. -* `OptionRepository` extends `CrudRepository` - -- -# Part 2.2 - Create interface `PollRepository` -* Create a `PollRepository` interface in the `repositories` subpackage. -* `PollRepository` extends `CrudRepository` - -- -# Part 2.3 - Create interface `VoteRepository` -* Create a `VoteRepository` interface in the `repositories` subpackage. -* `VoteRepository` extends `CrudRepository` - - - - - - - -- -# Part 3 - Controller Implementation -* _Controllers_ provides all of the necessary [endpoints](https://en.wikipedia.org/wiki/Web_API#Endpoints) to access and manipulate respective domain objects. - * REST resources are identified using URI endpoints. -* Create a sub package of `io.zipcoder.tc_spring_poll_application` named `controller`. - - -- -# Part 3.1 - Create class `PollController` -* Create a `PollController` class in the `controller` sub package. - * `PollController` signature should be `annotated` with `@RestController` - -* `PollController` has a `pollRepository` instance variable of type `PollRepository` - * `pollRepository` should be `annotated` with `@Inject` - -- -# Part 3.1.1 - Create `GET` request method -* 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. - -```java -@RequestMapping(value="/polls", method= RequestMethod.GET) -public ResponseEntity> getAllPolls() { - Iterable allPolls = pollRepository.findAll(); - return new ResponseEntity<>(allPolls, HttpStatus.OK); -} -``` - -* The method above begins with reading all of the polls using the `PollRepository`. -* We then create an instance of `ResponseEntity` and pass in `Poll` data and the `HttpStatus.OK` status value. -* The `Poll` data becomes part of the response body and `OK` (code 200) becomes the response status code. - - - - -- -# Part 3.1.2 - Testing via Postman -* Ensure that the `start-class` tag in your `pom.xml` encapsulates `io.zipcoder.springdemo.QuickPollApplication` -* Open a command line and navigate to the project's root directory and run this command: - * `mvn spring-boot:run` -* Launch the [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) app in your Chrome browser and enter the URL `http://localhost:8080/polls` and hit Send. -* Because we don’t have any polls created yet, this command should result in an empty collection. - - - - -- -# Part 3.1.3 - Create `POST` request method -* We accomplish the capability to add new polls to the `PollController` by implementing the `POST` verb functionality in a `createPoll` method: - -```java -@RequestMapping(value="/polls", method=RequestMethod.POST) -public ResponseEntity createPoll(@RequestBody Poll poll) { - poll = pollRepository.save(poll); - return new ResponseEntity<>(null, HttpStatus.CREATED); -} -``` - -* Take note that the method - * has a parameter of type `@RequestBody Poll poll` - * `@RequestBody` tells Spring that the entire request body needs to be converted to an instance of Poll - * delegates the `Poll` persistence to `PollRepository`’s save method - * `poll = pollRepository.save(poll);` - - - - -- -# Part 3.1.4 - Modify `createPoll` -* 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. - -```java -URI newPollUri = ServletUriComponentsBuilder - .fromCurrentRequest() - .path("/{id}") - .buildAndExpand(poll.getId()) - .toUri(); -``` - -* Modify the `createPoll` method so that it returns a `ResponseEntity` which takes an argument of a `new HttpHeaders()` whose _location_ has been _set_ to the above `newPollUri` via the `setLocation` method. - - - - -- -# Part 3.1.5 - Create `GET` request method -* The code snippet below enables us to access an individual poll. -* The _value attribute_ in the `@RequestMapping` takes a URI template `/polls/{pollId}`. -* The placeholder `{pollId}` along with `@PathVarible` annotation allows Spring to examine the request URI path and extract the `pollId` parameter value. -* Inside the method, we use the `PollRepository`’s `findOne` finder method to read the poll and pass it as part of a `ResponseEntity`. - -```java -@RequestMapping(value="/polls/{pollId}", method=RequestMethod.GET) -public ResponseEntity getPoll(@PathVariable Long pollId) { - Poll p = pollRepository.findOne(pollId); - return new ResponseEntity<> (p, HttpStatus.OK); -} -``` - - - +# Pagination +* To optimize performance, it is important to limit the amount of data returned, especially in the case of a mobile client. +* REST services have the ability to give clients access large datasets in manageable chunks, by splitting the data into discrete pages or _paging data_. +* For this lab, we will approach this by implementing the _page number pagination pattern_. - -# Part 3.1.6 - Create `UPDATE` request method -* The code snippet below enables us to update a poll. - -```java -RequestMapping(value="/polls/{pollId}", method=RequestMethod.PUT) -public ResponseEntity updatePoll(@RequestBody Poll poll, @PathVariable Long pollId) { - // Save the entity - Poll p = pollRepository.save(poll); - return new ResponseEntity<>(HttpStatus.OK); -} -``` - +### Get Data From Page +* For example, a client wanting a blog post in page 3 of a hypothetical blog service can use a `GET` method resembling the following: +`http://blog.example.com/posts?page=3` - -# Part 3.1.7 - Create `DELETE` request method. - -* The code snippet below enables us to delete a poll. - -```java -@RequestMapping(value="/polls/{pollId}", method=RequestMethod.DELETE) -public ResponseEntity deletePoll(@PathVariable Long pollId) { - pollRepository.delete(pollId); - return new ResponseEntity<>(HttpStatus.OK); -} -``` - - - +### Limit Data Retrieved From Page +* It is possible for the client to override the default page size by passing in a page-size parameter: +`http://blog.example.com/posts?page=3&size=20` - -# Part 3.1.8 - Test -* Restart the QuickPoll application. -* Use Postman to execute a `PUT` to `http://localhost:8080/polls/1` whose request body is the `JSON` object below. -* 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. - -```JSON -{ - "id": 1, - "question": "What's the best netflix original?", - "options": [ - { "id": 1, "value": "Black Mirror" }, - { "id": 2, "value": "Stranger Things" }, - { "id": 3, "value": "Orange is the New Black"}, - { "id": 4, "value": "The Get Down" } - ] -} -``` - +### Pagination Specific Information +* Pagination-specific information includes + * total number of records + * total number of pages + * current page number + * page size - -# Part 3.2 - Create class `VoteController` -* Following the principles used to create `PollController`, we implement the `VoteController` class. -* Below is the code for the `VoteController` class along with the functionality to create a vote. -* The `VoteController` uses an injected instance of `VoteRepository` to perform `CRUD` operations on Vote instances. - -```java -@RestController -public class VoteController { - @Inject - private VoteRepository voteRepository; - - @RequestMapping(value = "/polls/{pollId}/votes", method = RequestMethod.POST) - public ResponseEntity createVote(@PathVariable Long pollId, @RequestBody Vote - vote) { - vote = voteRepository.save(vote); - // Set the headers for the newly created resource - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setLocation(ServletUriComponentsBuilder. - fromCurrentRequest().path("/{id}").buildAndExpand(vote.getId()).toUri()); - return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED); - } -} -``` - -# Part 3.2.1 - Testing `VoteController` -* To test the voting capabilities, `POST` a new Vote to the `/polls/1/votes` endpoint with the option object expressed in `JSON` below. -* On successful request execution, you will see a Location response header with value http://localhost:8080/polls/1/votes/1. +### Pagination Data +* In the above scenario, one would expect a response body with pagination infromation closely resembling the `JSON` object below. ```JSON { - "option": { "id": 1, "value": "Black Mirror" } -} -``` - - - - -- -# Part 3.2.2 - Modify `VoteRepository` -* The method `findAll` in the `VoteRepository` retrieves all votes in a Database rather than a given poll. -* To ensure we can get votes for a given poll, we must add the code below to our `VoteRepository`. - -```java -public interface VoteRepository extends CrudRepository { - @Query(value = "SELECT v.* " + - "FROM Option o, Vote v " + - "WHERE o.POLL_ID = ?1 " + - "AND v.OPTION_ID = o.OPTION_ID", nativeQuery = true) - public Iterable findVotesByPoll(Long pollId); +"data": [ + ... Blog Data + ], + "totalPages": 9, + "currentPageNumber": 2, + "pageSize": 10, + "totalRecords": 90 } ``` - -* The custom finder method `findVotesByPoll` takes the `ID` of the `Poll` as its parameter. -* The `@Query` annotation on this method takes a native SQL query along with the `nativeQuery` flag set to `true`. -* At runtime, Spring Data JPA replaces the `?1` placeholder with the passed-in `pollId` parameter value. - - - - - - -- -# Part 3.2.3 - Modify `VoteController` -* Create a `getAllVotes` method in the `VoteController` - - -```java -@RequestMapping(value="/polls/{pollId}/votes", method=RequestMethod.GET) -public Iterable getAllVotes(@PathVariable Long pollId) { - return voteRepository. findByPoll(pollId); -} -``` - - - - - -- -- -# Part 4 - Data Transfer Object (DTO) Implementation -* The final piece remaining for us is the implementation of the ComputeResult resource. -* 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 -* Create a sub package of `java` named `dtos` - -- -# Part 4.1 - Create class `OptionCount` -* The `OptionCount` DTO contains the `ID` of the option and a count of votes casted for that option. - -```java -public class OptionCount { - private Long optionId; - private int count; - - public Long getOptionId() { - return optionId; - } - - public void setOptionId(Long optionId) { - this.optionId = optionId; - } - - public int getCount() { - return count; - } - - public void setCount(int count) { - this.count = count; - } -} -``` - -# Part 4.2 - Create class `VoteResult` -* The `VoteResult` DTO contains the total votes cast and a collection of `OptionCount` instances. - -```java -import java.util.Collection; -public class VoteResult { - private int totalVotes; - private Collection results; - - public int getTotalVotes() { - return totalVotes; - } - - public void setTotalVotes(int totalVotes) { - this.totalVotes = totalVotes; - } - - public Collection getResults() { - return results; - } - - public void setResults(Collection results) { - this.results = results; - } -} -``` - - -# Part 4.3 - Create class `ComputeResultController` -* Following the principles used in creating the `PollController` and `VoteController`, we create a new `ComputeResultController` class - -```java -@RestController -public class ComputeResultController { - @Inject - private VoteRepository voteRepository; - - @RequestMapping(value = "/computeresult", method = RequestMethod.GET) - public ResponseEntity computeResult(@RequestParam Long pollId) { - VoteResult voteResult = new VoteResult(); - Iterable allVotes = voteRepository.findVotesByPoll(pollId); - - // Algorithm to count votes - return new ResponseEntity(voteResult, HttpStatus.OK); - } -``` - - -* We inject an instance of `VoteRepository` into the controller, which is used to retrieve votes for a given poll. -* The `computeResult` method takes `pollId` as its parameter. -* The `@RequestParam` annotation instructs Spring to retrieve the `pollId` value from a HTTP query parameter. -* The computed results are sent to the client using a newly created instance of `ResponseEntity`. - - -# Part 4.4 - Test via Postman -* Start/restart the `QuickPoll` application. -* Using the earlier Postman requests, create a poll and cast votes on its options. -* 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 +* Read more about REST pagination in Spring by clicking [here](https://dzone.com/articles/rest-pagination-spring). + + +- +# Taking Action! + +0. Create a `src/main/resource/import.sql` file with [DML statements](http://lmgtfy.com/?q=DML+statement) for populating the database upon bootstrap. The `import.sql` should insert at least 10 polls, each with 3 or more options. + * Below is an example of `SQL` statements for creating a single poll with only one option. + + * Poll Creation + + ```sql + insert into poll (poll_id, question) values (1, 'What is your favorite color?'); + ``` + * Option Creation + + ```sql + insert into option (option_id, option_value, poll_id) values (1, 'Red', 1); + ``` + +0. Restart your application. +* Ensure database is populated by `import.sql`. +* Utilize Spring's built-in page number pagination support by researching the `PagingAndSortingRepository` class. +* Ensure the `Controller` methods handle `Pageable` arguments. +* Send a `GET` request to `http://localhost:8080/polls?page=0&size=2` via Postman. + * Ensure the response is a `JSON` object with pagination-specific information. \ No newline at end of file From 8ae0df5a11c6882ad180ce336187f13cf5ff1cc7 Mon Sep 17 00:00:00 2001 From: Git-Leon Date: Fri, 21 Jul 2017 01:52:41 -0400 Subject: [PATCH 5/9] Update README.md --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0329172..a004575 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -- # Pagination * To optimize performance, it is important to limit the amount of data returned, especially in the case of a mobile client. * REST services have the ability to give clients access large datasets in manageable chunks, by splitting the data into discrete pages or _paging data_. @@ -44,7 +43,7 @@ - # Taking Action! -0. Create a `src/main/resource/import.sql` file with [DML statements](http://lmgtfy.com/?q=DML+statement) for populating the database upon bootstrap. The `import.sql` should insert at least 10 polls, each with 3 or more options. +1. Create a `src/main/resource/import.sql` file with [DML statements](http://lmgtfy.com/?q=DML+statement) for populating the database upon bootstrap. The `import.sql` should insert at least 10 polls, each with 3 or more options. * Below is an example of `SQL` statements for creating a single poll with only one option. * Poll Creation @@ -58,9 +57,9 @@ insert into option (option_id, option_value, poll_id) values (1, 'Red', 1); ``` -0. Restart your application. -* Ensure database is populated by `import.sql`. -* Utilize Spring's built-in page number pagination support by researching the `PagingAndSortingRepository` class. -* Ensure the `Controller` methods handle `Pageable` arguments. -* Send a `GET` request to `http://localhost:8080/polls?page=0&size=2` via Postman. - * Ensure the response is a `JSON` object with pagination-specific information. \ No newline at end of file +2. Restart your application. +3. Ensure database is populated by `import.sql`. +4. Utilize Spring's built-in page number pagination support by researching the `PagingAndSortingRepository` class. +5. Ensure the `Controller` methods handle `Pageable` arguments. +6. Send a `GET` request to `http://localhost:8080/polls?page=0&size=2` via Postman. + * Ensure the response is a `JSON` object with pagination-specific information. From bb06ee7e09b7a92fa38df2d243e5e6ae2ba89e0e Mon Sep 17 00:00:00 2001 From: Git-Leon Date: Fri, 21 Jul 2017 02:19:08 -0400 Subject: [PATCH 6/9] Update README.md --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a004575..163ca7a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Pagination +# Part 6 - Pagination * To optimize performance, it is important to limit the amount of data returned, especially in the case of a mobile client. * REST services have the ability to give clients access large datasets in manageable chunks, by splitting the data into discrete pages or _paging data_. * For this lab, we will approach this by implementing the _page number pagination pattern_. @@ -41,9 +41,9 @@ - -# Taking Action! +# Part 6.1 - Load Dummy Poll Data -1. Create a `src/main/resource/import.sql` file with [DML statements](http://lmgtfy.com/?q=DML+statement) for populating the database upon bootstrap. The `import.sql` should insert at least 10 polls, each with 3 or more options. +* Create a `src/main/resource/import.sql` file with [DML statements](http://lmgtfy.com/?q=DML+statement) for populating the database upon bootstrap. The `import.sql` should insert at least 15 polls, each with 3 or more options. * Below is an example of `SQL` statements for creating a single poll with only one option. * Poll Creation @@ -57,9 +57,12 @@ insert into option (option_id, option_value, poll_id) values (1, 'Red', 1); ``` -2. Restart your application. -3. Ensure database is populated by `import.sql`. -4. Utilize Spring's built-in page number pagination support by researching the `PagingAndSortingRepository` class. -5. Ensure the `Controller` methods handle `Pageable` arguments. -6. Send a `GET` request to `http://localhost:8080/polls?page=0&size=2` via Postman. +* Restart your application. +* Use Postman to ensure database is populated by `import.sql`. + + +# Part 6.2 - Spring's Built-in Pagination +* Make use of Spring's built-in page number pagination support by researching `org.springframework.data.repository.PagingAndSortingRepository`. +* Modify respective `Controller` methods to handle `Pageable` arguments. +* Send a `GET` request to `http://localhost:8080/polls?page=0&size=2` via Postman. * Ensure the response is a `JSON` object with pagination-specific information. From cb73403841133e719556cef7dc7e1417680210fa Mon Sep 17 00:00:00 2001 From: Git-Leon Date: Fri, 21 Jul 2017 02:20:10 -0400 Subject: [PATCH 7/9] Update README.md --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 163ca7a..2f43038 100644 --- a/README.md +++ b/README.md @@ -15,16 +15,13 @@ `http://blog.example.com/posts?page=3&size=20` - -### Pagination Specific Information +### Pagination Data * Pagination-specific information includes * total number of records * total number of pages * current page number * page size - -- -### Pagination Data -* In the above scenario, one would expect a response body with pagination infromation closely resembling the `JSON` object below. +* In the above scenario, one would expect a response body with pagination information closely resembling the `JSON` object below. ```JSON { From 5554f1e87e2013c1c4ebcfa497ef6b1fb57533ee Mon Sep 17 00:00:00 2001 From: Git-Leon Date: Fri, 21 Jul 2017 02:23:58 -0400 Subject: [PATCH 8/9] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2f43038..0dc2f10 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ - ### Get Data From Page - * For example, a client wanting a blog post in page 3 of a hypothetical blog service can use a `GET` method resembling the following: `http://blog.example.com/posts?page=3` @@ -62,4 +61,4 @@ * Make use of Spring's built-in page number pagination support by researching `org.springframework.data.repository.PagingAndSortingRepository`. * Modify respective `Controller` methods to handle `Pageable` arguments. * Send a `GET` request to `http://localhost:8080/polls?page=0&size=2` via Postman. - * Ensure the response is a `JSON` object with pagination-specific information. +* Ensure the response is a `JSON` object with pagination-specific information. From a183884f158ebb43e66beb7c944fcc18e79305e3 Mon Sep 17 00:00:00 2001 From: Git-Leon Date: Fri, 21 Jul 2017 02:24:29 -0400 Subject: [PATCH 9/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0dc2f10..7fff81b 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ * Restart your application. * Use Postman to ensure database is populated by `import.sql`. - +- # Part 6.2 - Spring's Built-in Pagination * Make use of Spring's built-in page number pagination support by researching `org.springframework.data.repository.PagingAndSortingRepository`. * Modify respective `Controller` methods to handle `Pageable` arguments.