Implementing a simple Web REST API server with Spring Boot + MySQL --Qiita
Outline Implement the domain layer according to the following design. Consider the architecture of Web API implemented by Spring Boot --Qiita
Create the following 3 classes as the domain layer.
├── domain
│ ├── object
│ │ └── User.java
│ ├── repository
│ │ └── UserRepository.java
│ └── service
│ └── UserService.java
User.java A class for expressing the concept of a user on an application. There is no particular behavior this time, just hold the necessary information. It is described briefly using Lombok.
User.java
package com.example.springapi.domain.object;
import lombok.Builder;
import lombok.Data;
/**
*User
*/
@Data
@Builder
public class User {
/**
*User ID
*/
private String id;
/**
*User information
*/
private String value;
}
※ Lombok @Data The following methods are created automatically.
Like this.
package com.example.springapi.domain.object;
import lombok.Builder;
/**
*User
*/
@Builder
public class User {
/**
*User ID
*/
private String id;
/**
*User information
*/
private String value;
public String getId() {
return this.id;
}
public String getValue() {
return this.value;
}
public void setId(String id) {
this.id = id;
}
public void setValue(String value) {
this.value = value;
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof User)) return false;
final User other = (User) o;
if (!other.canEqual((Object) this)) return false;
final Object this$id = this.getId();
final Object other$id = other.getId();
if (this$id == null ? other$id != null : !this$id.equals(other$id)) return false;
final Object this$value = this.getValue();
final Object other$value = other.getValue();
if (this$value == null ? other$value != null : !this$value.equals(other$value)) return false;
return true;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $id = this.getId();
result = result * PRIME + ($id == null ? 43 : $id.hashCode());
final Object $value = this.getValue();
result = result * PRIME + ($value == null ? 43 : $value.hashCode());
return result;
}
protected boolean canEqual(Object other) {
return other instanceof User;
}
public String toString() {
return "User(id=" + this.getId() + ", value=" + this.getValue() + ")";
}
}
@Builder Instance creation can be described in a method chain. I like this. You can create a User instance like this.
String id;
String value;
User user = User.builder()
.id(id)
.value(value)
.build();
Actually, the following code is generated by Lombok.
package com.example.springapi.domain.object;
import lombok.Data;
/**
*User
*/
@Data
public class User {
/**
*User ID
*/
private String id;
/**
*User information
*/
private String value;
@java.beans.ConstructorProperties({"id", "value"})
User(String id, String value) {
this.id = id;
this.value = value;
}
public static UserBuilder builder() {
return new UserBuilder();
}
public static class UserBuilder {
private String id;
private String value;
UserBuilder() {
}
public UserBuilder id(String id) {
this.id = id;
return this;
}
public UserBuilder value(String value) {
this.value = value;
return this;
}
public User build() {
return new User(id, value);
}
public String toString() {
return "User.UserBuilder(id=" + this.id + ", value=" + this.value + ")";
}
}
}
UserRepository.java Interface between domain layer and infrastructure layer. The interface you want to use at the domain layer is defined here. This interface reverses the dependencies between the domain layer and the infrastructure layer (the principle of dependency reversal).
UserRepository.java
package com.example.springapi.domain.repository;
import com.example.springapi.domain.object.User;
import java.util.Optional;
/**
*Interface with infrastructure layer
*/
public interface UserRepository {
/**
*User search
*
* @param id User ID you want to search
* @return user
*/
Optional<User> findById(String id);
/**
*User created and updated
*
* @param user User created and updated
* @return User after update
*/
User save(User user);
/**
*Delete user
*
* @param id User ID you want to delete
*/
void deleteById(String id);
}
UserService.java A class that describes unnatural business logic is written in User.java. Manipulate the persisted user information using the interface defined earlier. The implementation class of UserRepository is solved by using the mechanism called DI container of Spring. (If there is no interface implementation, you will still get a compile error at this point.)
UserService.java
package com.example.springapi.domain.service;
import com.example.springapi.domain.object.User;
import com.example.springapi.domain.repository.UserRepository;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Optional;
/**
*User operation logic
*/
@Service
@RequiredArgsConstructor
public class UserService {
@NonNull
private final UserRepository userRepository;
/**
*User search
*
* @param id User ID you want to search
* @return user
*/
public Optional<User> findById(String id) {
return this.userRepository.findById(id);
}
/**
*User created and updated
*
* @param user User created and updated
* @return User after update
*/
public User save(User user) {
return this.userRepository.save(user);
}
/**
*Delete user
*
* @param id User ID you want to delete
*/
public void deleteById(String id) {
this.userRepository.deleteById(id);
}
}
In Spring, DI is implemented by a mechanism called DI container.
A.java
public class A {
private B b = new B();
}
Class A ** depends on Class B **.
In Spring, there is a mechanism called DI container that automatically injects an instance into the declared variable. By adding @Autowired, an instance is automatically created and injected.
A.java
@Compornent
public class A {
@Autowired
private B b;
}
B.java
@Compornent
public class B {
}
However, the granted Autowired is valid only ** when the class (A) to be injected is obtained via the DI container **. That is, if you new class A like a normal Java application, b remains null. Therefore, when using Autowired, it is necessary to register itself in the DI container. There are various ways to register in a container, but in Spring Boot, it is basically registered by assigning @Compornent to the class. The @Service used this time is an alias for @Compornent.
The DI of Spring has the following notation. IntelliJ gets angry when I do field injection. (For various reasons such as reusability, invariance of instances, and explicit dependency) There is also setter injection, but I have not used it, so I will omit it.
--Field injection
@Compornent
public class A {
@Autowired
private B b;
}
--Constructor injection
@Compornent
public class A {
private B b;
@Autowired
public A(B b) {
this.b = b;
}
}
@Autowired can be omitted if there is only one constructor. If you use the annotation of Lombok's constructor generation, you can omit it so far.
@RequiredArgsConstructor
@Compornent
public class A {
@NonNull
private final B b;
}
Recommended Posts