How to make a Java Spring Boot project?
This article is aimed at novice Back-end programmers, in particular Java, because here will go through the process of planning and programming a server in Java Spring Boot with PostgreSQL database
The subject of analysis will be my team project work for the 2nd year of the university:
application for creating and watching art house movies
The application was taken over by my partner, so I had no choice but to watch films provide it with a server
Planning
Having selected the main functionality, an MVP is born, the purpose of which is to determine the interest of users in such films
To meet these requirements, we decided to show the user the following screens:
registration / login
account page
film catalog
movie page with player
chat for discussion
And provide for the following interaction: adding movies to favorites, comments and likes / dislikes in comments
Then, together with a partner, we discussed:
movie and user entities
required entity queries
security
Having said all this, I was eager to start creating the database architecture. This only required knowledge about the types of relationships between entities. [1:1, 1:N, M:N]
Programming
I’ll go through my code in chronological order
TangoApplication
The entry point to the application. At the beginning there is nothing here, however, it is worth noting 1 curious detail: a lot in Spring Boot is done through annotations
@SpringBootApplicaion
– annotation that is generated automatically and configures default settings
In addition to the main method In this class, you can define a commandLineRunner to do any actions when the server starts, in this case, the starting values are thrown into the base there
@Bean
– instructs Spring to take this method into account under the hood
@Transactional
–

Controllers
This is the API that a front-end specialist will communicate to through requests. Its functionality was determined at the planning stage.
The controller in the picture is the most common class, with a special annotation @RestController(path="api/common")
Within this class, methods are defined that can be accessed for a specific purpose, in slang they are called “pens”. To define a handle, a number of annotations are used for different types of queries: @GetMapping
,@PostMapping
etc
To use them correctly, you should look at the following topics:
request types
accepting arguments and request parameters
getting request body

It is worth remembering that the specialist from the Front-end has not received anything yet. And this is not surprising, neither the database nor the entity was created, however, to create the functionality on its part, real data is not required
Fake data in the correct format is called a Mock. You can return a pre-generated object or, if the answer is not large, then fields in a similar form:
Map<String, Object> response = new HashMap<>();
response.put("message", "Test data");
response.put("number", 1)
return ResponseEntity.ok(response);
It is not difficult to make such stubs for at least some part of the API. By deploying the server, the Back-end and Front-end will become less dependent on each other. Slang: deployment == deploy
Let the API be known, however, the frontend will not go into the server code to find out the question: “How to use it?” It was convenient for us to keep the API in Postman, where I created a collection that contained requests with all the arguments and their body
Models
Let’s move on to the most important thing, entities and databases
First of all, we connect to the database. We define the required fields in application.properties and then, using the Database tab on the right in IntelliJ, to the database itself. In the community version of IntelliJ, you will have to resort to the help of other articles / videos to solve this problem.
The picture below shows the user entity
Some of the annotations here are from the Lombok library, which is designed to shorten the object’s code, thereby making it more readable
@Data
– defines getter and setter for each entity, adds toString, equals, hashcode methods
@NoArgsConstructor
– creates a constructor with no arguments

К сущности:
@Entity — обозначается сущность
@Table — таблица
@Data @NoArgsConstructor — аннотации Lombok. Реализуют некоторые методы
@JsonIncude(JsonInclude.NON_NULL) — при сериализации в JSON попадают все поля, которые не NULL
К полю:
@JsonProperty(value="название") — при сериализации будет указывать тебе определённое имя
@Column(name = "колонка") — нужно, чтобы задать название для колонки в базе данных
@Transient — означает, что это поле будет вычисляться во время запроса
К ID:
@Id, @SequenceGenerator, @GeneratedValue — нужно для того, чтобы создать ID
Отношения между сущностями:
@OneToOne, @ManyToOne, @OneToMany, @ManyToMany,
@JsonBackReference, @JsonManagedReference
About@JoinTable
and relationships between entities are best read at Baeldung
How to write queries to a PostgreSQL database without SQL?
→ The modern approach to building queries to the database in Spring Boot is implemented through special classes – repositories
@Repository
– indicates that this is a repository
@JpaRepository<сущность, тип_её_ID>
– includes all prepared queries to address a specific entity
To create author’s queries, you need to name functions in a special format, or using annotation @Query
write SQL
To do pagination, you need to use Page<сущность>
– container for multiple instances of the entity and add to function arguments Pageable pageable
DTO
→ Data Transfer Object – needed to transfer entities reduced by fields within the server: operate with them in requests / receive from the database, etc.
Their use is due to the fact that the language is typed and it is impossible to remove a property from objects on the fly.
// Пример DTO: Тело запроса на регистрацию
@Data
public class SignupRequestDTO {
private String email;
private String username;
private String password;
private LocalDate date_of_birth;
private LocalDate sub_deadline;
private Set<String> roles;
private String avatar;
public User fromWithoutRoles() {
return new User(email, username, password, date_of_birth, sub_deadline);
}
}
Services
It is too cumbersome to write logic in controllers, so it was thrown into special classes with annotation @Service
and from there they call the required method for a specific request
It is considered good practice to make an interface with the necessary methods next to the entity, and then implement this interface with the Impl postfix

@Autowired
– this is one of the key concepts of Spring “Dependency Injection”: all these dependencies are registered inside Spring and then they can be inserted somewhere via annotation
Services use repositories, or older variations of logic for queries to the database
Tests
At one point, I felt that there is functionality that I do not want to test through requests. This thought became the starting point for writing tests.

Security
The topic of security is incredibly extensive and it is worth starting with the question: “What are the general possibilities of authentication?”
The github repository contains my version of the implementation of working with JWT, based on adding MiddleWare for authorization
MiddleWare is a function that requests are sent to before they end up in controllers, so it is convenient to put a check for a JWT token there.
Utils
→ Logic that is used in different places, but not directly related to entities
In the project, I brought out the internal logic for encrypting / decrypting the JWT token, functions for uploading pictures to Imgur
Where to keep secrets?
→ In the file application.properties
Constants are defined there, which can then be accessed through the annotation. @Value
Moreover, the server can start with certain arguments, which include values for these very constants.
// Где-либо
@Value("${jwt.jwtSecret}")
private String jwtSecret;
@Value("${jwt.jwtExpirationMs}")
private int jwtExpirationMs;
// В application.properties
jwt.jwtSecret=секрет
jwt.jwtExpirationMs=86400000
Conclusion
The github repository contains code for a number of unaffected topics:
Building a Front-end chat site using JS, CSS and HTML
Chat on WebSocket from the browser side, which is true, I don’t really like it right now
Security with JWT
Custom error class
This was a general view of creating a small project from the Back-end.