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.
I had researched it once around 2017, and the composition at that time is as follows.
--Example of existing system configuration
--Structure after REST API growth
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.
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.
Start by creating an app from Spring Initializr. I made it with the following settings.
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)
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.
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.
Up to this point, you have easily (?) Created a Web API for the DB. Finally, it supports OpenAPI and SwaggerUI.
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.
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. .. ..
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.
https://github.com/omix222/springdatarestsample
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