Level 7 - Milestone 8
Milestone 8 - Improving the Results
In this section we will improve the results we return to our users, by limiting what we give
them
to only the information they are interested in.
Before completion of this milestone, students will:
- Add a Data Transfer Object that will hold the result we received from the external service
- Ignore any fields from that request which we are not interested in returning to our users
Creating a Data Transfer Object
Currently we are receiving the data from the external service as a String. A much better option
is to accept it in the form of a custom Java object that represents the data we receive. As a Java
object,
we can much more easily manipulate the response within our application. This process is simple
once
we have created the data transfer object.
To create the object, we could of course start from scratch and make it ourselves, but there
are tools available that we can use to create a Java object (or objects) that represents the
data contained in the JSON response. We will use jsonschema2pojo.org. All that needs to be done
is to take a sample response that we received from a request to the service. We will also want
to
make sure to enter an appropriate name for the class, there are a few other options to select:
- Target Language:
- Java
- Source Type
- JSON
- Annotation Style
- Jackson 2.x
You may find that the sample response you submit contains too many results for the generator to work. You can use a JSON formatter to properly format the JSON, which will make it easier to delete all of the results except for one.
Add the DTO to the Project
Create a package name "dto" inside of the repository package, and deposit the newly-created Java object(s) there.
Using the DTO
@ApiOperation(value = "Searches for articles matching the search term", notes = "Response may include multiple Result values.", response = Result.class, responseContainer="List") @ApiResponses(value = { @ApiResponse(code = 200, message = "Result(s) found"), @ApiResponse(code = 404, message = "Result(s) not found") })
Getting Rid of Unwanted Fields
It is likely that there are a number of fields returned from the external service which we are
uninterested in giving to our users. Unfortunately, jsonschema2pojo includes a lot of annotations
which we do not need. We could have asked it to not include any annotations, but then
all of the field names would have been converted to camel case with no indication of whether they are
represented in snake case in the JSON we will receive.
First, we can remove any fields from the objects which we do not want to return to our users.
Next, we can remove all annotations in the DTO class(es). However, at this point we want to make sure
to annotate any fields that are original in snake case with an @JsonAlias("original_name") annotation. We
can also use this opportunity to rename the fields in the Java class itself to be more appropriate if necessary, also indicating
this difference from the JSON field with the @JsonAlias annotation.
After all the changes are made, if you rerun the application and test out the endpoint from the Swagger UI,
you should no longer see the unnecessary fields, and and any renamed fields should show up accordingly.
Returning 404 Status When No Results Are Found
In the swagger notations for our LocController class, we have already state that the application will return a status code of 404 if there are no results found, it's time to make good on that promise. Remember that status codes are meant to succinctly tell the user the result of their request. In the event they provide a bad search term, it would be much nicer for us to simply tell them there were no results found than give them an empty list as a result. Notice this is similar to how it works with webpages, if you navigate to a subpage that doesn't exist, instead of simply displaying a blank html page, you receive a status of 404, meaning "not found". This can be accomplished in our code by updating the LocController method to something like the following:
List<Result>LocController results = locService.getResults(query); if(CollectionUtils.isEmpty(results)){ throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Result(s) not found."); } return results;
Summary of Code Changes for this Milestone
-
Cheetah-Search
- src
- main
- java
- org.jointheleague.level7.cheetah
- config
- ApiDocConfig.java
- presentation
- HomeController.java
- LocController.java
- service
- LocService.java
- repository
- resources
- application.yml
- build.gradle