Building a RESTful Web Service Using Java

Igor Zelaya
The Startup
Published in
9 min readSep 9, 2020

Introduction

Due to its exponential growth, REST(Representational State Transfer) has rapidly become the “de-facto” Software Architecture for developing Web Services. This is no surprise considering his creator, Roy Fielding, who was involved in maybe around a dozen specs that contribute to how the web operates now. REST architectural style was developed in the 2000s. Parallel to HTTP(Hyper-Text Transfer Protocol) 1.1 which was developed from 1996–1999 based on its previous design, HTTP 1.0.

In this article, we will go step-by-step on developing a Web Service based on REST architecture. Without further ado, you will be needing the following:

  • A prior, mid to advanced knowledge on Java Object-Oriented Programming Language.
  • A development System with an IDE of your preference.
  • JDK 8 or above installed.
  • A Relational DBMS with its own SQL Server (MySQL, MongoDB, PostgreSQL).
  • Postman development tool for testing APIs. (Optional)

Getting Started

Let’s assume a Software Entrepreneur has a brand-new, innovative, Software as a Service. He wants to keep account of his clients, store them onto a DataBase, and manage them whenever he feels like it. For this, we will make use of the Spring Framework, which will provide us with the ability to run a Spring Boot Application. This will initialize a microservice for our application. We will develop a web server with HTTP request methods, such as GET, POST, and DELETE.

  1. First, we will be creating our Spring Boot project. To create a Spring Boot project you can install the Spring Framework plug-in on your IDE, copy the following URL as your service URL https://start.spring.io or you can head directly to Spring Initializr to create a local repository. If this is the case, select Maven project and specify your Java version. Remember to configure your project with your own specifications. Click Generate and it will start to download a .zip file. Unzip it and you’ll be good to go.
  2. Your Spring project will consist of a pom.xml file. Add the following dependencies which we will be using later.

SpringBoot Starter data JPA(Java Persistence API) dependency

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-jpa</artifactId></dependency>

SpringBoot Starter Web Dependency

<dependency>

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId></dependency>

You also need to add your JDBC(Java Database Connection) driver dependency for your corresponding DBMS. In my case, I am using MySQL so my connector dependency is shown below.

<dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId></dependency>

Note: You can search for your respective JDBC Driver here https://mvnrepository.com/

Finally, your pom.xml file should look like this:

3. Well done, your Spring project is set with all dependencies attached to the XML file. Next, we’ll define our DTO(Data Transfer Object) class which will be used to transfer data in and out of our Database.

Note: We won’t go into detail on Databases and table creation since it is out of the scope in this article.

Let’s review the content in the class above.

Our DTO class consists of a series of attributes with their corresponding getter and setter methods, these attributes are also our columns in our Database Table.

We’ll emphasize on the annotations provided.

Entity is a JPA annotation. It tells our API that our class corresponds to an entity and is ready for storage in a JPA-based Data Store.

JsonSerialize and JsonProperty annotations are both parts of the Jackson library. It is defined by the Jackson wiki page as the “recommended way to register a custom serializer”, JsonSerialize is meant for serializing JsonProperties — such as our attributes in this class — when we don’t have access to the ObjectMapper class used to serialize and deserialize, also referred by other developers as “Hydrate” and “Dehydrate”. For more information on serialization, click this link.

The Table and Id annotations are also both JPA annotations, Table specifies both the Database name as well as the table name in which our Entity will be stored. The id annotation should be placed onto the attribute that acts as the primary key in our table.

The Column annotation is used to avoid error proneness, we use it to specify the exact name of the column in our table in which our object will be stored. We should always have a default constructor with its corresponding getter and setter methods besides the one that initializes all field variables in our class.

Tip: I am aware most developers use Long-type variables for their Id, even though this can actually be done. I prefer making use of the UUID(Uniform Universal Resource Identifier) class and recommend you implement it in your code as well. This class will automatically assign an Id to each Prospect without having to worry about duplicates. UUID assigns random Id’s to your prospects in hexadecimal positional system. e.g., 0x2AF3. For more information on the UUID class check the Oracle documentation here.

Note: The ProspectStatus class for prospectStatusCode attribute is defined on an ENUM class which we won’t cover. Full source code available at https://github.com/igorzelaya-io/LeadManagement-Back-end.git.

4. Now, we’ll cover our interface.

We use the CRUDRepository — which is part of JPA — as our superclass.

The CRUD Repository enables us to do CRUD(Create, Read, Update, and Delete) operations on a specified object. In our case, we will perform these operations on Prospect data. CRUD Repository establishes a connection “under the hood” with your database via JDBC(Java Database Connection) and JPA, so you don’t have to worry about connecting to your database using DataSource or DriverManager classes.

For extended documentation on CRUD Repository click here.

5. We’re now about to instantiate our ProspectRepository interface — which extends a CRUD Repository — using a dependency injection.

Now we can make use of the CRUD Repository methods. They are shown above, but for clarity purposes I’ll list them below.

  • Update and Create:
Prospect prspct = prospectRepo.save(prspct);
  • Delete:
Prospect prspct = prospectRepo.delete(prspct);
  • Read:
Iterable<Prospect> allProspects = prospectRepo.findAll();Prospect prspct = findByProspectEmail(String prospectEmail).get();

6. Next up we will configure our Controller class, for mapping HTTP request methods such as GET, POST, DELETE. I know this may be a little bit intimidating for some programmers who are just starting on web development. At least it was for me, but don’t worry, I’ll guide you on everything you should know about this RestController class.

Let’s review our Controller class.

The RestController annotation simplifies the development of RESTful web services. Before RestController was introduced, the Controller and RequestBody annotations did the work, RestController was introduced in Spring 4.0. Its main objective is to transform the response into JSON or XML format, depending on your REST configuration.

DeleteMapping, GetMapping, and PostMapping annotations map the HTTP request onto a handler method. Logically, GetMapping maps the GET request method, PostMapping maps the POST request method, and so on. Before these annotations were introduced, RequestMapping annotation did the same thing with a different syntax. e.g.

@RequestMapping(value = "/prospects", method = RequestMethod.GET);

This is how it was done before. Now, GetMapping and the rest do the RequestMapping implicitly.

@GetMapping("/prospects")

Both these statements shown above have the same functionality.

For each Mapping annotation, a handler method gets attached to a URL. In the case of the GET request method shown on the source code above, we can notice the findByProspectMail handler method returns a List of Prospects. We can also notice the RequestParam annotation is thrown onto its String-type, prospectMail parameter, this annotation indicates the String prospectMail is required on the URL for this method to return a response. This is very common when doing GET request methods due to the fact that we need to specify the entity we wish to be returned. In this case, we specify that our String parameter(prospectMail) is required on the URL. Our service URL should look then look like this.

http://localhost:8080/prospects?prospectMail=i@z.com

I’ll dive a little bit further into this URL. Localhost indicates the webserver is running on your machine. 8080 is the port number in which your web server is being listened, and as you can notice, prospectMail is now part of our URL. If the RequestParam is not placed into the URL, it would most likely return a 404 status code, meaning the page was not found.

Note: If the value assigned to your mail doesn’t exist i.e. isn’t placed on your database. Your page will crash.

In our POST handler method, we specify our method should contain a RequestBody, meaning we need a body with data to post. In this case, a Prospect with its respective data. That is the reason we throw a Prospect object as a parameter. Normally, in a web server, there is a UI(User Interface), where we enter information. Maybe on a dialog box or select information from a drop-down. This information is parsed into JSON or XML format so the back end service can process it. In this case, we will enter information directly in JSON format. There are two different ways to achieve this process. The first and simplest way of doing this is by using Postman, the second is by using the cURL in the Command Prompt. We will discuss the use of Postman and cURL commands in just a sec. For now, let us review how our JSON data should be structured. It should look like this.

{
"prospectId":"0x857",
"prospectName":"Igor",
"prospectOrgName":"Baas",
"prospectPhone":"+504 0000-0005",
"prospectCountry":"HN",
"prospectMail":"a@b.com",
"prospectStatusCode":"2",
"prospectComments":"He is good at cod"
}

Note: If your DTO has more attributes, you should list them in the same way.

Finally, we’ll review our DELETE handler method deleteProspect. It is very similar to our GET handler method, the only difference is the RequestParam annotation. The parameter passed into the handler method is now prospectId, there is a reason for this. Besides from REST’s architecture norms and documentation, the fact that our prospectId is the primary key in our database allows the process of searching for a specific prospect to be carried out in much less time. This is kind of a rule of thumb, if you’re searching for an entity, make sure to look either for a primary, secondary, or foreign key.

7. You are set with the controller class, open your Spring project or Local Repository, and head to src/main/resources. There, you will find an application.properties file. If not, just create it. Enter the following configuration.

spring.datasource.url=jdbc:mysql://localhost:PORT/LeadManagmentDBspring.datasource.username=YOUR_USERNAMEspring.datasource.password=YOUR_PASSWORDspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=updatespring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpllogging.level.org.hibernate.SQL=DEBUGlogging.level.org.hibernate.type=trace

Note: Make sure to type in your own Database speculations.

Congratulations, your application is ready to be compiled. Run a maven install on it. If you did everything correctly, your console should present the following information.

BUILD SUCCESS

Once you’ve compiled your project successfully, you can run your project as a Spring Boot Application, this will initialize a microservice hosted on your machine. If everything goes okay you should have your application up and running.

Testing

Okay, if you’ve made it this far, you might as well test your application. If you have Postman installed, we’ll get right into it. Else, head to Terminal(Command Line Interface), and type in the following command.

Using Terminal:

curl --location --request POST 'http://localhost:8080/prospects' \--header 'Content-Type: application/json' \--data-raw '{"prospectId":"435678","prospectName":"Maria","prospectOrgName":"baas","prospectPhone":"000000000","prospectCountry":"HN","prospectEmail":"b@a.com","prospectStatusCode":"3","prospectComments":"he is tall."}'

This command will POST a Prospect on your Database, you can access it by going to your browser and entering this in your URL.

http://localhost:8080/prospects?prospectMail=b@a.com

This will run a GET request method on whichever prospect corresponds to the email entered on the RequestParam.

Using Postman:

To GET, POST, and DELETE information using Postman, it’s a lot easier.

To POST a prospect, you just need to click on the drop-down, select POST HTTP request method, and fill the body in raw JSON format, just as shown below. When you’re done, click send. Your response message should pop in the console.

For GET and DELETE request methods, things have a twist.

In this case, our handler methods are composed of a RequestParam annotation, meaning we need to specify the Prospect we are searching for either by indicating its mail or by typing its ID. Click send and you’ll get your response message in no time.

Conclusion

This is a back end service application, this can be further extended by adding more tables and relate them with one another, but for this article, I kept it pretty basic so you can really grasp the idea of REST software architecture. To automate this, even more, a UI would fit in perfectly, but that has the caliber for a full different article. I hope this article was helpful, enjoy the REST of your day.

--

--

Igor Zelaya
The Startup

Back end Developer, currently mastering Spring framework and Angular as a side hustle.