#MyFirstTechSeries — Micro-service using Spring Boot

Nishanthi Grashia Suresh
8 min readAug 3, 2021

Originally published in : https://www.numpyninja.com/post/my-first-microservice

Welcome back to My First Tech Series (#MyFirstTechSeries). Today we will see how to create a simple micro service. Our service will perform CRUD operations on customer data such as customer name, city and email address. We will use Postgres SQL as our backend and use swagger for testing.

STEP 1: INSTALLATION OF SPRING PLUG-IN

  • To begin, we need to have Spring Tool Suite installed in our IDE. For that, navigate to Help → Eclipse Marketplace. Search for “Spring Tools” and hit Go. Choose to install Spring Tools 4.
  • Hit Confirm, Accept Terms and Conditions and hit Finish.
  • Please wait till the software is installed. Look out for the progress bar in the bottom right corner of eclipse IDE.
  • After installation, eclipse will ask for restart. Click Restart Now.

STEP 2: CREATE THE FIRST PROJECT

  • Navigate to FileNewOtherSpring Starter Project
  • Give a name for your micro service. I have chosen demo-rest-service. Also give the group and package name. I have given com.ninja.demo. A general best practice is to give com.companyname.projectname. Also modify the description if necessary
  • Hit Next..

Add necessary dependencies. You can add them directly from here or you can later add in to the pom.xml file. For this project, I am choosing the following:

  1. Spring Web
  2. Spring Data JDBC — for having a JDBC Connection for data access.
  3. Postgres SQL Server — this is the DB we will be using. You can choose based on your DB.
  4. Spring Data JPA — to avoid unnecessary boilerplate code. This helps in significantly reducing our coding efforts.
  5. Lombok — generates code using easy annotations. to avoid boilerplate code. Example: It automatically creates getter setter methods for entity object.
  • Add all the dependencies. Click Next > and Finish.

Project is created successfully in eclipse with all our chosen dependencies available in pom.xml. This is our created project structure.

We are done with the project creation. We will move on with the next step.

STEP 3: SETTING UP THE POSTGRES SERVER

  • Download the Postgres SQL from here based on your OS and install in your system : https://www.postgresql.org/download/ At the time of writing, the version is 13.3. If you use this installation method, ignore the next bullet about brew.
  • As applicable, give the following details:

Username: postgres

Password : admin

Port : 5432 (This is default port for postgress, advisable not to change this)

  • Alternatively, You can also use brew to install in your system. I used brew. Note: It does take a few minutes to install using brew. If you use brew, then the installation command is
brew install postgresql
brew install --cask pgadmin4
  • Now open pgAdmin 4 in your system. Provide a master password for pgAdmin. I have given the password as “admin”. I know it’s not safe, but it is easy to remember.

STEP 4: STARTING THE SPRING BOOT SERVER

Set up Application Port:

  • Often times, we get exception that “Port is already in use”. To avoid this, it is always a best practice to have a dedicated port for the server. Port Number can be anything. I chose 1234. To set this port number, goto src/main/resources application.properties . In that file, type
server.port=1234
  • Then, we have to give Postgres SQL properties. (Username, password, url etc). Also, we have to In the same file, also type create tables in Postgres and keep modifying the table based on our entity object definition.
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=admin
spring.jpa.hibernate.ddl-auto=update
  • The final application.properties file is as follows:
#Server Properties
server.port=1234
#PostGres Properties
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=admin
#To create tables in PostGres if not already created
spring.jpa.hibernate.ddl-auto=update
  • Save the application.properties file.
  • Now let us test if the server is running. Navigate to src/main/java → package com.ninja.demoDemoRestServiceApplication.java.
  • Right click Run AsSpring Boot App
  • Console output’s last line should be: “Started DemoRestServiceApplication”.

If you have reached this far, then you have successfully finished your project setups. Give yourself a pat on your back, as you have crossed more than half the sea.

STEP 5: CODING THE APPLICATION- PACKAGE AND CLASS CREATION

  • The best codes often lie in organized packages. So, let us create packages first and then create classes within. Under com.ninja.demo package, Right clickNewPackage. The packages to be created are:

com.ninja.demo.controller ← This is for the controller

com.ninja.demo.entity ← This is for entity / object / model layer

com.ninja.demo.jpa ← This is for the service repository and database access layer

  • After creating packages, create java classes under the respective packages. The filenames to be created are:

DemoController.java under com.ninja.demo.controller

DemoEntity.java under com.ninja.demo.entity

DemoRepository.java under com.ninja.demo.jpa

STEP 6: CODING THE APPLICATION- DEPENDENCY CONFIGURATION

We must add a few dependencies manually to our pom.xml. Remember to Clean and Build the project after any modification to the pom.xml

  1. Spring boot starter validation → Necessary for Entity Validations
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2. javax.persistence → Necessary for Entity, ID auto generation etc.

<!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>

3. Jpa → Necessary for JPA repository

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.5.3</version>
</dependency>

4. Springfox — Swagger and Swagger UI

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
  • After adding all dependencies, our final pom.xml code will be as follows. Make sure to clean the project for any changes in pom.xml to be reflected in the build.
<?xml version=”1.0" encoding=”UTF-8"?><project xmlns=”http://maven.apache.org/POM/4.0.0"xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.3</version><relativePath /> <! — lookup parent from repository →</parent><groupId>com.ninja</groupId><artifactId>demo-rest-service</artifactId><version>0.0.1-SNAPSHOT</version><name>demo-rest-service</name><description>Demo project for Spring Boot — First Microservice</description><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><! — <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency> →<! — https://mvnrepository.com/artifact/org.projectlombok/lombok →<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><! — https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api →<dependency><groupId>javax.persistence</groupId><artifactId>javax.persistence-api</artifactId><version>2.2</version></dependency><! — https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa →<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId><version>2.5.3</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.7.0</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.7.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

STEP 7: CODING THE APPLICATION- CREATE THE MODEL/ENTITY/OBJECT

  • First let us create the model / entity. We create 3 fields — Customer Name, Email and City along with autogenerated Customer ID. All annotations necessary for the Entity (Getter, Setter, Constructors etc.) are also included.
package com.ninja.demo.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class DemoEntity {

@Id
@GeneratedValue (strategy = GenerationType.AUTO)
Long customerID;
@NotBlank (message = "Customer Name is mandatory")
String customerName;
String customerEmail;
String customerCity;
}

STEP 8: CODING THE APPLICATION- CREATE THE REPOSITORY/SERVICE

  • Next up is the DemoRepository.java. If the logic is complicated, we may require an additional file DemoService.java. But since we are having a simple logic, just DemoRepository.java is sufficient. JpaRepository has inbuilt functions. The code is as follows:
package com.ninja.demo.jpa;import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.ninja.demo.entity.DemoEntity;
@Repository
public interface DemoRepository extends JpaRepository<DemoEntity, Long> {

}

STEP 9: CODING THE APPLICATION- CREATE THE CONTROLLER AND DEFINE REST ENDPOINTS/METHODS

We have to define the service endpoints for different methods(Get, Post, Put, Delete) in the controller DemoController.java. The code is as follows:

package com.ninja.demo.controller;import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ninja.demo.jpa.DemoRepository;
import com.ninja.demo.entity.DemoEntity;
@RestController
@RequestMapping("/")
public class DemoController {

// DemoEntity is the Customer Object

@Autowired
DemoRepository demoRepository;

// Get All Customers
@GetMapping("/customers")
List<DemoEntity> all(){
return demoRepository.findAll();
}

// Get Single Customer
@GetMapping("/customers/{id}")
Optional <DemoEntity> findCustomer(@PathVariable Long id){
return demoRepository.findById(id);
}

// Create New Customer
@PostMapping("/customers")
DemoEntity createCustomer (@RequestBody DemoEntity newCustomer) {
return demoRepository.save(newCustomer);
}

// Update Customer Information
@PutMapping("/customers/{id}")
DemoEntity updateCustomer (@RequestBody DemoEntity updatedCustomer, @PathVariable Long id) {
return demoRepository.save(updatedCustomer);
}

// Delete Single Customer
@DeleteMapping ("/customers/{id}")
void deleteCustomer(@PathVariable Long id){
demoRepository.deleteById(id);
}

}

STEP 10: CODING THE APPLICATION- TIE IT ALL TOGETHER

  • Finally, the spring application’s main class should know the packages containing the entity, service and controller. Hence, we should add a ComponentScan annotation in the DemoRestServiceApplication.java. Also, we must include swagger specification here. The source code is as follows.
package com.ninja.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
//@ComponentScan({ "com.ninja.demo.controller, com.ninja.demo.entity, com.ninja.demo.jpa" })
@ComponentScan(basePackages="com.ninja.demo")
@EnableSwagger2
public class DemoRestServiceApplication {
public static void main(String[] args) {
SpringApplication.run(DemoRestServiceApplication.class, args);
}

@Bean
public Docket demoApi() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.basePackage("com.ninja.demo")).build();
}
}

STEP FINAL: TEST THE SERVICES

  • Start the server.
  • Test the different methods using a rest client such as postman. We have already included coding for Swagger and hence we can use swagger to test our services.
  • The Swagger UI URL is : http://localhost:1234/swagger-ui.html
  • Create / POST JSON sample body for single entry is:
{
"customerName": "Jane Doe",
"customerEmail": "janeDoe@ninja.com",
"customerCity": "Seattle"
}
  • Create / POST JSON sample body for multiple entries is:
[
{
{
"customerName": "Ron Weasley",
"customerEmail": "Ron@hp.com",
"customerCity": "London"
},
{
"customerName": "Harry Potter",
"customerEmail": "Harry@hp.com",
"customerCity": "Dallas"
},
{
"customerName": "Hermione Granger",
"customerEmail": "EmmaWatson@hollywood.com",
"customerCity": "New York"
}
]
  • When we look at the Postgres DB, a table named demo_entity has been created automatically and our data has been successfully.
  • Note that all our table names and field names are automatically snake_cased.

Thats it…. You have reached the end of the tutorial..

Congratulations on this great achievement..

And I hope this saved you a lot of time.. See you soon in the next post..

--

--