Dreaming of easily creating a Web API for the DB of an existing Java system

What you want to do with the background

What do you do when you want to access the data in the DB of an existing monolithic system with the REST API? When I ask the person in charge of the system to publish the REST API, I don't understand a little, I have to think about the impact of the infrastructure, and I'm busy now, and sometimes I don't get serious about it. maybe.

In such a case, is it possible to create a REST-style Web API very easily while using the existing environment? I thought.

Past review

I had researched it once around 2017, and the composition at that time is as follows.

--Example of existing system configuration image.png

--Structure after REST API growth image.png

As for the configuration of tools made with lightweight Spring Boot, isn't it easy to configure Spring Boot + Spring Data REST + Spring Fox? I thought. This is because it was a project that was attracting attention in the Spring community at that time.

Spring Data REST: In cooperation with Spring Data series, the access part from the outside is converted to REST API.

SpringFox: Spring project unofficial. It will automatically find the Rest API in your project and automatically generate an OpenAPI document. It also prepares a client (Swagger-UI) that calls the API from the document.

After trying a little, it worked pretty well, so I thought it was good. On the other hand, if you look at it again recently, the last release of Spring Fox stopped in June 2018, Spring version supports up to 4 series. The issue of support for Spring 5 series has also been turned off, but the support is not fixed, so I searched for other alternatives and decided to make a sample.

This study

I decided to make the subject app first. Suppose you have a Student table in your existing monolith system and want to poke it with the REST API.

App creation

Start by creating an app from Spring Initializr. I made it with the following settings.

image.png

Create Entity of the table you want to get. You need the key, but only the fields you want to get.

Student.java


@Entity
public class Student {
    @Id
    private String id;
    private String name;
    private String className;
    //After that Getter,Setter etc.

Next, create a Repository to access the DB. First of all, make it normally so that it can be called from the Controller without feeling Data REST.

StudentRepository.java


@Repository
public interface StudentRepository extends PagingAndSortingRepository<Student,String> {
    Iterable<Student> findAll();
}

Controller has the following implementation.

StudentRestController.java


@RestController
public class StudentRestController {
    @Autowired
    private StudentRepository studentRepository;

    @GetMapping("/students") Iterable<Student> getStudents() {
        return studentRepository.findAll();
    }
}

This time, I will access the DB using H2, so I will put in various settings. To make it easier to experiment later, the initial SQL is flowed, and the settings to make the data at the end of the application persistent are included.

application.properties


# datasource
spring.datasource.driver-class-name=org.h2.Driver
#Save the persistence destination as a DB file in the h2db folder. I wanted to use ON CONFLICT when initializing the data, so I set it to PostgreSQL mode.
spring.datasource.url=jdbc:h2:./h2db/sandbox;MODE=PostgreSQL
spring.datasource.username=dev
spring.datasource.password=dev
# resources/sdata.Initialize DB data using sql every time the application is launched
spring.datasource.initialization-mode=always

#Persist data to file
spring.jpa.hibernate.ddl-auto=update

# h2 for debug tool
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.web-allow-others=true

If you keep it in this state and put the following files under resources, it will create a table and input initial data (do nothing if there is one). Is it a function of Spring Data? It's convenient.

data.sql


CREATE TABLE IF NOT EXISTS STUDENT (
 ID VARCHAR(255) NOT NULL,
 CLASS_NAME VARCHAR(255),
 NAME VARCHAR(255),
 PRIMARY KEY(ID)
);
--Use ON CONFLICT to avoid unique constraints
INSERT INTO STUDENT VALUES ('1','A CLASS','TAKA')
    ON CONFLICT DO NOTHING;
INSERT INTO STUDENT VALUES ('2','A CLASS','KASHI')
    ON CONFLICT DO NOTHING;
INSERT INTO STUDENT VALUES ('3','B CLASS','KIKUCHI')
    ON CONFLICT DO NOTHING;

It was a long time, but this completes WebAPI development with Spring Boot + REST Controller. Keep in mind that you haven't used Spring Data REST so far. The result of launching the SpringBoot app and accessing it with Curl is as follows. (Reference: jq is a command line tool for formatting and processing JSON) image.png

Next, we will incorporate Spring Data REST. However, it is extremely easy because there are only 3 steps (minimum 2 steps). Add dependency to pom.xml.

pom.xml


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

Addition of RepositoryRestResource annotation to StudentRepository class

StudentRepository.java


@Repository
@RepositoryRestResource
        (collectionResourceRel = "students", path = "students")
public interface StudentRepository extends PagingAndSortingRepository<Student,String> {

(Optional) Add base path for API automatically created by Spring Data REST

application.properties


#API base path automatically created by SpringDataREST
spring.data.rest.basePath=/api

That's it. Relaunch the app and try accessing localhost: 8080 / api. You can see that SpringDataREST automatically generated the REST API.

image.png

Since the API of URI called api / students has been created, you can get the following results by accessing it. Did you notice that there is more information than the API you created earlier? SpringDataREST is HATEOAS, so it has a lot of information and is advantageous for using API from clients such as JavaScript. image.png

Up to this point, you have easily (?) Created a Web API for the DB. Finally, it supports OpenAPI and SwaggerUI.

What is the alternative to SpringFox?

I googled with SpringDataRest, OpenAPI and tried using Springdoc OpenAPI that came out first. Probably Spring official, as far as I can see the URL. Since the formula has come out, if the development of Spring Fox has slowed down, it is a convincing flow. ..

It's an introduction method, but just add it to the dependency. I remember that JavaConfig creation was indispensable for SpringFox, but it seems that Starter is prepared here.

pom.xml


        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.1.44</version>
        </dependency>

After adding the dependency, you can touch the Swagger UI by restarting the application and accessing http: //localhost:8080/swagger-ui/index.html? Url = / v3 / api-docs with a browser. I will! It is the best because you can see the list of WebAPI and you can actually execute WebAPI from here.

image.png

I was delighted, but if you look closely, the first thing that is displayed in this UI is the REST Controller. Only the ones made with Spring Data REST are not made.

SpringFox did it for me, but when I was thinking about it, I arrived at the following issue.

Documentation is available on the official page: https://springdoc.github.io/springdoc-openapi-demos/ Spring Data Rest is not a priority. It will be supported on a future release.

It was closed by this comment. .. .. In another comment below, I'm trying to switch from SpringFox to SpringDoc, but I can't switch because it doesn't have this function.

What a mess. Is it wrong for me to enjoy using SpringDataRest? Certainly, there are cases where the project was started using Spring Data Rest and stopped in the middle. I understood that too much dependence is NG, but I thought it would be good for making a mess. .. ..

Conclusion

So, at the moment, it seems difficult to easily realize DB direct access Web API construction using Spring Boot, which everyone loves.

If you have read this far, some people may find it easier to build from the REST Controller. At the moment, it seems that there is no choice but to make it steadily by that method.

Since Java execution environment is everywhere around us, Spring Boot is easy and good. I thought, but I will investigate it in the future without being bound by that idea.

Source code created by verification

https://github.com/omix222/springdatarestsample

Future reference

It will be DB-specific, but there seems to be something called PostgREST. https://qiita.com/kanedaq/items/0c3097604d0e86afd1e3

REST API is supported in Cosmos DB, which is a DB of MS cloud. https://docs.microsoft.com/ja-jp/rest/api/cosmos-db/

There are many products. Like CDATA API Server. But I want to do it with an open product instead of a paid product. somehow.

Recommended Posts

Dreaming of easily creating a Web API for the DB of an existing Java system
Easily get an integer from a system property in Java
A story about hitting the League Of Legends API with JAVA
How to check for the contents of a java fixed-length string
The story of introducing Gradle as a retrofit to an existing system that did not manage packages
Compare the elements of an array (Java)
A story about Java 11 support for Web services
About the description order of Java system properties
ChatWork4j for using the ChatWork API in Java
Measure the size of a folder in Java
A collection of simple questions for Java beginners
The road to creating a Web service (Part 1)
I wrote a test code (Junit & mockit) for the code that calls the AWS API (Java)
Basics of HTML forms indispensable for creating web applications
Get a list of MBean information for Java applications
[For beginners] Quickly understand the basics of Java 8 Lambda
Use Java lambda expressions outside of the Stream API
[Java] When writing the source ... A memorandum of understanding ①
Java: Timed token management class for Web API authentication
Links for each version (Japanese version) of Java SE API
A survey of the Kubernetes native Java framework Quarkus
A memorandum for creating an extended logger using org.slf4j.Logger
A brief explanation of a maze game made in Java for a cousin of an elementary school student
A summary of what Java programmers find when reading Kotlin source for the first time