Accessing MongoDB over REST

In this recipe, we will see how to access MongoDB and perform CRUD operations using REST APIs. We will use spring-data-rest for REST access and spring-data-mongodb to perform the CRUD operations. Before you continue with this recipe, it is important to know how to implement the CRUD repositories using spring-data-mongodb. Refer to the Developing using spring-data-mongodb recipe in this chapter to know how to use this framework.

The question one must be having is, why is a REST API needed? There are scenarios where there is a database that is being shared by many applications and is possibly written in different languages. Writing JPA DAO or using spring-data-mongodb is good enough for Java clients but not for clients in other languages. Having APIs locally with the application doesn't even give us a centralized way to access the database. This is where REST APIs come into play. We can develop the server-side data access layer and the CRUD repository in Java—spring-data-mongodb to be precise—and then expose it over a REST interface for a client written in any language to invoke them. We not only invoke our API in a platform-independent way, but also provide a single point of entry into our database.

Getting ready

Apart from the prerequisites of the spring-data-mongodb recipe, we have a few more requirements for this recipe. The first thing is to download the SpringDataRestTest project from the Packt website and import it to your IDE as a maven project. Alternatively, if you do not wish to import to the IDE, you can run the server servicing the requests from the command prompt, which we will see in the next section. There is no specific client application used to perform the CRUD operations over REST. I will be demonstrating the concepts using the Chrome browser and a special plugin of the Advanced REST Client browser to send HTTP POST requests to the server. The tools can be found under the Developer Tools section of the Chrome web store.

How to do it…

  1. If you have imported the project in your IDE as a maven project, execute the com.packtpub.mongo.cookbook.rest.RestServer class, which is the bootstrap class and starts the server locally that would accept client connections.
  2. If the project is to be executed from the command prompt as a maven project, go to the root directory of the project and run the following:
    mvn spring-boot:run
    
  3. The following line on the command will be seen on the command prompt if all goes well and the server has been started:
    [INFO] Attaching agents: []
    
  4. After starting the server in either way, enter http://localhost:8080/people in the browser's address bar and we should see the following JSON response. This response is seen because the underlying person collection is empty.
    {
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/people{?page,size,sort}",
          "templated" : true
        },
        "search" : {
          "href" : "http://localhost:8080/people/search"
        }
      },
      "page" : {
        "size" : 20,
        "totalElements" : 0,
        "totalPages" : 0,
        "number" : 0
      }
    }
  5. We will now insert a new document in the person collection using an HTTP POST request to http://localhost:8080/people. We will be sending a POST request to the server using the Advanced REST Client Chrome extension. The document posted is:
    {"lastName":"Cruise", "firstName":"Tom", "age":52, "id":1}.
    

    The request's content type is application/json.

    The following image shows the POST request sent to the server and the response from the server:

    How to do it…
  6. We will now query this document from the browser using the _id field, which is 1 in this case. Enter http://localhost:8080/people/1 in the browser's address bar. You should see the document that we inserted in step 3.
  7. Now that we have one document in the collection, (you can try to insert more documents for people with different names and, more importantly, a unique ID.) we will query the document using the last name. First, type the following URL in the browser's address bar to view the entire search options available: http://localhost:8080/people/search. We should see one search method, findByLastName, that accepts a command line parameter, lastName.
  8. To search by the last name, Cruise in our case, enter the following URL in the browser's address bar: http://localhost:8080/people/search/findByLastName?lastName=Cruise.
  9. We will now update the last name and age of the person with the ID 1, Tom Cruise for now. Let's update the last name to Hanks and the age to 58. To do this, we will be using the HTTP PATCH request and the request will be sent to http://localhost:8080/people/1, which uniquely identifies the document to update. The body of the HTTP PATCH request is {"lastName":"Hanks", "age":58}. Refer to the following image for the request that we sent out for an update:
    How to do it…
  10. To validate whether our update went through successfully or not (we know it did as we got a response status 204 after the PATCH request), enter http://localhost:8080/people/1 again in the browser's address bar.
  11. Finally, we delete the document. This is straightforward, and we simply send a DELETE request to http://localhost:8080/people/1. Once the DELETE request is successful, send an HTTP GET request from the browser to http://localhost:8080/people/1 and we should not get any document in return.

How it works…

We will not be reiterating the spring-data-mongodb concepts again in this recipe, but will look at some of the annotations that we added specifically for the REST interface to the repository class. The first one is on the top of the class name, as follows:

@RepositoryRestResource(path="people")
public interface PersonRepository extends PagingAndSortingRepository<Person, Integer> {

This is used to instruct the server that this CRUD repository can be accessed using the people resource. This is the reason why we always make HTTP GET and POST requests on http://localhost:8080/people/.

The second annotation is in the findByLastName method. We have the following method signature:

Person findByLastName(@Param("lastName") String lastName);

Here, the method's lastName parameter is annotated with the @Param annotation, which is used to annotate the name of the parameter that will have the value of the lastName parameter that will be passed while invoking this method on the repository. If we look at step 6 in the previous section, we can see that findByLastName is invoked using an HTTP GET request, and the value of the URL lastName parameter is used as the string value passed while invoking the repository method.

Our example here is pretty simple with just one parameter used for the search operation. We can have multiple parameters for the repository method and an equal number of parameters in the HTTP request that will be mapped to these parameters for the method to be invoked on the CRUD repository. For some types, such as dates to be sent out, use the @DateTimeFormat annotation, which will be used to specify the date and time format. Refer to the spring Javadocs at http://docs.spring.io/spring/docs/current/javadoc-api/ for more information on this annotation and its usage.

This was all about the GET request that we made to the REST interface to query and search data. We initially created a document data sending an HTTP POST request to the server. To create new documents, we would always be sending a POST request—with the document to be created as the body of the request—to the URL identifying the REST endpoint, in our case, http://localhost:8080/people/. All documents posted to this collection would be making use of PersonRepository to persist Person in the corresponding collection.

Our final two steps were to update person and delete person. The HTTP request types to perform these operations are PATCH and DELETE, respectively. In step 7, we updated the document for the person Tom Cruise and updated his last name and age. To achieve this, our PATCH request is sent to a URL identifying a specific person instance, which is http://localhost:8080/people/1. Note that in case of creating a new person, our POST request was always sent to http://localhost:8080/people, as against the PATCH and DELETE requests, where we sent the HTTP request to a URL representing the specific person that we want to update or delete. In the case of update, the body of the PATCH request is JSON whose provided fields would replace the corresponding fields in the target document to update. All the other fields would be left as is. In our case, lastName and the age of the target document were updated and firstName was left untouched. In case of delete, the message body was not empty, and the DELETE request itself indicates that the target to which the request was sent should be deleted.

You can also send a PUT request instead of PATCH to a URL, identifying a specific person; in which case, the entire document in the collection would get updated or replaced with the document provided as part of the PUT request.

See also

The spring-data-rest home is at http://projects.spring.io/spring-data-rest/, where you can find links to its Git repository, reference manual, and Javadocs URL.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset