DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Frameworks
  4. How to Write Your Own Spring Boot REST Service

How to Write Your Own Spring Boot REST Service

Save time writing framework components and boilerplate code with the Spring Boot REST service.

Amit Phaltankar user avatar by
Amit Phaltankar
·
Jan. 31, 19 · Tutorial
Like (5)
Save
Tweet
Share
23.36K Views

Join the DZone community and get the full member experience.

Join For Free

In this article, we will write our own Spring Boot REST Service from scratch. Spring Boot’s auto-configuration comes in handy when you want to concentrate on your business rather than spend time writing framework components and boilerplate code.

Today, we will create a Simple RESTful Service. So first, let’s write a Dog Service. The quickest way to get on with a Spring Boot project is to use the Spring Initializr.

Tutorial Outline:

  1. Create a Spring Boot project
  2. Mock Data Provider
  3. Create Dogs Controller with the GET, POST, and DELETE methods.
  4. See the Dogs Service running

Note:

  • Use mock repository instead of the actual data store
  • Here is a separate article on Spring REST Service Exception Handling
  • Keep unit tests out of scope. (we will cover testing REST services in a separate tutorial).

1. Create Spring Boot Project

Let’s write our basic project components.

1.1 build.gradle

As of now, we have added spring-boot-starter-web — denoting we want to build a web application — and Lombok dependencies.

Lombok helps to get rid of typical boiler plate code, and I always love using it. I generally use Lombok to avoid writing Constructors, Getters, Setters, etc. Visit Project Lombok for more information.
buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.amitph.spring'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    compile('org.projectlombok:lombok:1.18.4')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}


1.2 Application.java

Here is our starting point — Application.java has the friendly public static void main method, where we can actually start a Spring Boot application.

package com.amitph.spring.dogs;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}


At this point, you have your Spring Boot application up and running. You can confirm by running the Application.java like any other Java class and see the server being up and listening for port 8080 (configurable).

2. Mock Data Provider

First, let’s start and create the Service and Data layer in the application. As mentioned above, we are not going to have a real data store in the tutorial, but we will use a mock data provider, which will act as a datastore for our needs.

2.1 MockDogProvider

Mock Dog Provider has an instance level pre-populated list of Dogs. The various CRUD methods in the class, actually perform the operation on the Dogs List.

package com.amitph.spring.dogs.repo;

import com.amitph.spring.dogs.model.DogDto;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class MockDogProvider {
    private List<Dog> mockDogStore;

    public MockDogProvider() {
        mockDogStore = new ArrayList<>();
        mockDogStore.add(Dog.of(1, "Benji", 10));
        mockDogStore.add(Dog.of(2, "Baxter", 9));
        mockDogStore.add(Dog.of(3, "Brinkley", 8));
        mockDogStore.add(Dog.of(4, "Daisy", 10));
        mockDogStore.add(Dog.of(5, "Cujo", 12));
    }

    public List<Dog> getDogs() {
        return mockDogStore;
    }

    public Dog findDogById(long id) {
        for (Dog dog : mockDogStore) {
            if (dog.getId() == id) {
                return dog;
            }
        }
        return null;
    }

    public void add(DogDto dto) {
        mockDogStore.add(Dog.of(dto.getId(), dto.getName(), dto.getAge()));
    }

    public void delete(long id) {
        int idx = 0;
        for (; idx < mockDogStore.size(); idx++) {
            if (mockDogStore.get(idx).getId() == id) {
                break;
            }
        }
        mockDogStore.remove(idx);
    }
}


2.2 DogsService

Dogs service is a routine Service Layer of our web application. It just decouples the controller and data provider. Because no business logic is involved, it just delegates the calls to Data Provider.

3. Controller

We are almost there. What we need in the end is a controller that handles the REST calls and delegate to Service.

package com.amitph.spring.dogs.web;

import com.amitph.spring.dogs.model.DogDto;
import com.amitph.spring.dogs.repo.Dog;
import com.amitph.spring.dogs.service.DogsService;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/dogs")
@RequiredArgsConstructor
@Setter
public class DogsController {
    @Autowired private final DogsService service;

    @GetMapping
    public List<Dog> getDogs() {
        return service.getDogs();
    }

    @PostMapping
    public void postDogs(@RequestBody DogDto dto) {
        service.add(dto);
    }

    @GetMapping("/{id}")
    public Dog getById(@PathVariable(required = true) long id) {
        return service.getDogById(id);
    }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable(required = true) long id) {
        service.delete(id);
    }
}


4. Run the Application

/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.0.RELEASE)

2018-11-28 10:04:21.905 INFO 2752 --- [ main] com.amitph.spring.dogs.Application : Starting Application on Amits-office-mac.local with PID 2752 (/Users/aphaltankar/Workspace/personal/dog-service/out/production/classes started by aphaltankar in /Users/aphaltankar/Workspace/personal/dog-service)
2018-11-28 10:04:21.908 INFO 2752 --- [ main] com.amitph.spring.dogs.Application : No active profile set, falling back to default profiles: default
2018-11-28 10:04:22.745 INFO 2752 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2018-11-28 10:04:22.760 INFO 2752 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-11-28 10:04:22.760 INFO 2752 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.12
2018-11-28 10:04:22.765 INFO 2752 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/aphaltankar/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
2018-11-28 10:04:22.837 INFO 2752 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-11-28 10:04:22.837 INFO 2752 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 893 ms
2018-11-28 10:04:22.857 INFO 2752 --- [ main] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-11-28 10:04:22.861 INFO 2752 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-11-28 10:04:22.861 INFO 2752 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-11-28 10:04:22.861 INFO 2752 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'formContentFilter' to: [/*]
2018-11-28 10:04:22.861 INFO 2752 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-11-28 10:04:23.044 INFO 2752 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2018-11-28 10:04:23.194 INFO 2752 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2018-11-28 10:04:23.197 INFO 2752 --- [ main] com.amitph.spring.dogs.Application : Started Application in 1.75 seconds (JVM running for 2.44)
2018-11-28 10:05:29.420 INFO 2752 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2018-11-28 10:05:29.420 INFO 2752 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2018-11-28 10:05:29.428 INFO 2752 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms


4.1 Get All Dogs

Open the browser and execute (GET)

http://localhost:8080/dogs

And below is the output:

[
   {
      "id":1,
      "name":"Benji",
      "age":10
   },
   {
      "id":2,
      "name":"Baxter",
      "age":9
   },
   {
      "id":3,
      "name":"Brinkley",
      "age":8
   },
   {
      "id":4,
      "name":"Daisy",
      "age":10
   },
   {
      "id":5,
      "name":"Cujo",
      "age":12
   }
]


4.2 Get Dog by Id

Let’s make a GET request:

http://localhost:8080/dogs/3

Output:

{
   "id":3,
   "name":"Brinkley",
   "age":8
}


4.3 Add New Dog

This is a POST request I will use curl to make this call.

curl -X POST \
  http://localhost:8080/dogs \
  -H 'Content-Type: application/json' \
  -H 'Postman-Token: c6813aea-146c-49cd-9eba-1370aad4bff9' \
  -H 'cache-control: no-cache' \
  -d '{
    "id": 6,
    "name": "Hooch",
    "age": 11
}'


After this execute the GET /dogs again and you will see a new dog has been added.

4.4 Delete a Dog

This a DELETE request using curl here.

curl -X DELETE \
  http://localhost:8080/dogs/5 \
  -H 'Content-Type: application/json' \
  -H 'Postman-Token: b4b93304-7ee7-45c2-917b-c3bc2985a250' \
  -H 'cache-control: no-cache


After this, you should see that Dog with id 5 is gone from the list.

5. Summary

So, we have created our Spring Boot REST Example. We created a Dog Service with a simple Create, GET, and DELETE endpoints. We have seen how easy a service is with Spring Boot where you can skip a lot of crap and concentrate on your business.

In the next article, we will refer to the Same Dog Service and learn Spring REST Service Exception Handling. We will learn how Spring takes care of all the crappy exceptions handling stuff and let us do more important things.

For the full source code of the examples used here, please visit https://github.com/amitrp/dog-service.

Spring Framework REST Web Protocols Spring Boot Web Service

Published at DZone with permission of Amit Phaltankar. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Apache Kafka vs. Memphis.dev
  • How to Quickly Build an Audio Editor With UI
  • Top 5 Node.js REST API Frameworks
  • Why Every Fintech Company Needs DevOps

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: