В этой статье я расскажу вам, как создать быстрый REST API с помощью Spring Boot.

Spring Boot — это популярная платформа для создания веб-приложений и RESTful API. Его мощные функции и простота использования делают его идеальным выбором для разработчиков, стремящихся создавать масштабируемые и надежные приложения.

Это руководство поможет вам создать простой REST API с использованием Spring Boot. Мы создадим простую конечную точку REST API для управления таблицей user в базе данных PostgreSQL.

Шаг 1: Создайте проект Spring Boot, используя https://start.spring.io/

Перейдем на сайт https://start.spring.io/ и создадим наш проект Spring Boot Rest API. Для сборки этого проекта мы будем использовать следующие весенние зависимости.

  1. База данных Postgresql
  2. Весенняя сеть
  3. Ломбок
  4. Данные Spring JPA
  5. Пакет JDBC
  • PostgreSQL: Здесь мы будем использовать PostgreSQL,систему управления базами данных с открытым исходным кодом для хранения, управления и извлечения пользовательских данных.
  • Spring Web: Spring Web, часть платформы Spring для создания веб-приложений с такими функциями, как MVC, службы RESTful и поддержка различных веб-технологий.
  • Lombok: Lombok будет использоваться в качестве библиотеки Java для сокращения шаблонного кода за счет создания стандартного кода, такого как геттеры, сеттеры и конструкторы.
  • Spring Data JPA: Spring Data JPA является частью среды Spring для упрощения доступа к данным с помощью JPA с такими функциями, как операции CRUD, разбивка на страницы и генерация запросов.
  • Пакет JDBC в Spring Boot: предоставляет стандартный способ подключения к базам данных из приложений Java, а Spring Boot предоставляет высокоуровневые абстракции для работы с базами данных.

Для создания стандартного кода из start.spring.io мы будем использовать следующие настройки.

Группа: com.tutcoach

Артефакт: userapi

Имя: userapi

Описание: REST API в весенней загрузке

Имя пакета: com.tutcoach.userapi

Упаковка: банка

Язык: Java 17

Диспетчер пакетов: maven

Нажмите generate, чтобы сгенерировать код

Откройте загруженный zip-файл с помощью IntelliJ или вашей любимой Java IDE, как показано ниже.

Не забудьте настроить Java 17 JDK в качестве SDK для вашего проекта.

Конфигурация базы данных Postgresql при загрузке Spring

В файле application.properties настройте путь к базе данных, имя пользователя и пароль для вновь созданного проекта.

spring.datasource.url=jdbc:postgresql://localhost:5432/idas
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=update

Эта конфигурация устанавливает соединение с базой данных PostgreSQL в приложении Spring Boot с указанием URL-адреса, имени пользователя, пароля и других свойств Hibernate.

Здесь,

spring.datasource.url: URL-адрес JDBC используется для подключения к серверу базы данных PostgreSQL, который работает на localhost с номером порта 5433 и именем базы данных das.

  • spring.datasource.username: имя пользователя, используемое при подключении к базе данных, в данном случае это postgres.
  • spring.datasource.password: пароль для подключения к базе данных, в данном случае также postgres.
  • spring.jpa.hibernate.ddl-auto: Режим гибернации DDL для автоматического создания, обновления или проверки схемы базы данных при запуске приложения. Здесь установлено значение update, которое автоматически создаст или обновит схему.
  • spring.jpa.hibernate.show-sql: Флаг, указывающий, следует ли регистрировать операторы SQL, сгенерированные Hibernate, для которого установлено значение true.
  • spring.jpa.properties.hibernate.dialect: для связи с базой данных используется диалект Hibernate, в данном случае это диалект PostgreSQL.

Создание пользовательского пакета

Создайте пакет user внутри пакета userapi со следующими файлами

  1. UserController.java
  2. UserEntity.java
  3. UserRepository.java
  4. UserService.java

Здесь,

В Spring Boot UserController, UserEntity и UserRepository, UserService связаны друг с другом и используются для реализации операций CRUD (создание, чтение, обновление, удаление) для управления пользовательскими данными в приложении.

Контроллер пользователя

Это класс Java, который действует как контроллер для HTTP-запросов, связанных с пользователями в приложении. Он обрабатывает входящие HTTP-запросы, проверяет вводимые пользователем данные, вызывает соответствующие методы UserEntity и UserRepository и отправляет обратно HTTP-ответы клиенту. Другими словами, он служит точкой входа для пользовательских запросов и отвечает за сопоставление входящих HTTP-запросов с определенной бизнес-логикой.

Пользовательская сущность

Этокласс Java, представляющий пользовательскую модель данных приложения. Он определяет атрибуты пользователя, такие как имя, адрес электронной почты, пароль и любую другую соответствующую информацию, которую приложение должно хранить о пользователе. UserEntity обычно снабжен аннотациями JPA (Java Persistence API), которые предоставляют необходимые метаданные для сопоставления класса Java с таблицей базы данных.

Репозиторий пользователя

Это интерфейс Java, который обеспечивает уровень абстракции между приложением и базой данных. Он определяет набор методов для доступа к пользовательским данным и управления ими, таких как save(), findById(), deleteById() и findAll(). Реализация этих методов осуществляется базовой структурой ORM (Object-Relational Mapping), такой как Hibernate, которая сопоставляет объекты Java с записями базы данных и наоборот.

Пользовательская служба

UserService.java используется в качестве посредника между контроллером и репозиторием в приложении Spring Boot. Он содержит бизнес-логику для работы с User объектами, такими как создание, получение, обновление и удаление пользователей.

Благодаря отделению бизнес-логики от уровней контроллера и репозитория код становится более модульным и его легче поддерживать. Контроллер отвечает за обработку HTTP-запросов и возврат ответов клиенту, а репозиторий отвечает за сохранение и извлечение данных из базы данных.

Класс UserService находится между этими уровнями, обрабатывая данные и бизнес-логику, необходимые для выполнения запросов, сделанных контроллером. Он взаимодействует с UserRepository для выполнения операций CRUD над объектом User и возвращает результаты контроллеру в формате, который может быть легко понят клиентом.

Вместе UserController, UserEntity и UserRepository составляют важную часть архитектуры приложения Spring Boot, позволяя разработчикам легко управлять пользовательскими данными с четким разделением задач между бизнес-логикой и уровнем доступа к данным.

Реализация UserEntity

Класс UserEntity имеет атрибуты id, email и username, как показано ниже.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String username;
    
    private String password;
    
    private String email;
}

Здесь,

  1. Операторы import импортируют необходимые классы для объекта, включая аннотацию Entity, аннотацию Id и аннотации Lombok.
  2. Аннотация @Entity используется для объявления того, что этот класс является сущностью в приложении. Сущности в JPA — это объекты, представляющие данные, которые можно хранить и извлекать из базы данных.
  3. Аннотация @Data — это аннотация Lombok, которая генерирует общие методы, такие как геттеры, сеттеры, equals(), hashCode() и toString() для всех нестатических полей в классе. В данном случае он генерирует все эти методы для полей id, username, password и email.
  4. Аннотация @NoArgsConstructor — это аннотация Lombok, которая генерирует конструктор без аргументов для класса. Это полезно для таких сред, как JPA, которым требуется конструктор по умолчанию для создания объектов сущностей.
  5. Аннотация @AllArgsConstructor — это аннотация Lombok, которая создает конструктор с аргументами для всех нестатических полей в классе. Это полезно для создания объектов со всеми инициализированными полями.
  6. Аннотация @Id — это аннотация JPA, которая помечает поле как первичный ключ объекта.
  7. Аннотация @GeneratedValue — это аннотация JPA, которая указывает, как должен быть сгенерирован первичный ключ. В этом случае GenerationType.IDENTITY указывает, что первичный ключ представляет собой автоматически сгенерированный столбец идентификации в базе данных.
  8. Поле private Long id представляет собой первичный ключ объекта.
  9. Поля private String username, private String password и private String email представляют атрибуты объекта пользователя.

Реализация UserRepository.java

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    User findByUsername(String username);
    
    User findByEmail(String email);
}

Здесь у нас есть интерфейс UserRepository.java, который расширяет интерфейс JpaRepository, предоставляемый Spring Data JPA.

JpaRepository — это мощный интерфейс, который предоставляет множество базовых операций CRUD, таких как создание, извлечение, обновление и удаление сущностей. Расширяя этот интерфейс, нам не нужно писать код реализации для этих основных операций, поскольку Spring Data JPA автоматически генерирует для нас код реализации на основе имен методов, которые мы определяем в интерфейсе.

@Repository — это аннотация, которая помечает этот интерфейс как компонент репозитория в контексте Spring. Это позволяет инфраструктуре Spring автоматически обнаруживать интерфейс и создавать его экземпляры во время выполнения.

Интерфейс UserRepository определяет два пользовательских метода findByUsername и findByEmail, которые позволяют нам извлекать User сущностей из базы данных на основе свойств username и email соответственно. Spring Data JPA автоматически генерирует код реализации для этих методов на основе их имен, и нам не нужно писать код реализации.

Таким образом, используя JpaRepository и имена пользовательских методов, мы можем легко выполнять операции CRUD над нашей сущностью User, а также реализовывать пользовательские запросы без написания шаблонного кода для операций сохранения.

Реализация UserService.java

package com.tutcoach.userapi.user;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
class UserService {
    private UserRepository userRepository;

    UserService(@Autowired UserRepository userRepository) {
        this.userRepository = userRepository;
    }


    public ResponseEntity<List<UserEntity>> getAllUsers() {
        List<UserEntity> users = (List<UserEntity>) userRepository.findAll();
        return new ResponseEntity<>(users, HttpStatus.OK);

    }

    public ResponseEntity<UserEntity> createUser(UserEntity user) {
        return new ResponseEntity<>(userRepository.save(user), HttpStatus.CREATED);
    }

    public ResponseEntity<UserEntity> updateUser(Long id, UserEntity user) {
        // find the user with that id
        Optional<UserEntity> dbUser = userRepository.findById(id);
        if (dbUser.isPresent()) {
            // update the user
            UserEntity updateDbUser = dbUser.get();
            updateDbUser.setEmail(user.getEmail());
            updateDbUser.setPassword(user.getPassword());
            userRepository.save(updateDbUser);
            return new ResponseEntity<>(updateDbUser, HttpStatus.CREATED);
        } else {
            // return not found
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

    }

    public ResponseEntity<UserEntity> getUser(Long id) {
        Optional<UserEntity> user = userRepository.findById(id);
        if (user.isPresent()) {
            return new ResponseEntity<>(user.get(), HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

    }

    public ResponseEntity<UserEntity> deleteUser(Long id) {
        try {
            userRepository.deleteById(id);
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }
}

Здесь, в приведенном выше коде

Класс UserService.java реализует операции CRUD для UserEntity с использованием UserRepository. Вот обзор класса и его методов:

  • Аннотация @Service используется для указания того, что этот класс является сервисным компонентом.
  • Аннотация @Autowired используется для внедрения экземпляра UserRepository в класс UserService.
  • Конструктор UserService инициализирует экземпляр UserRepository с предоставленной аннотацией @Autowired.
  • Метод getAllUsers извлекает всех пользователей из базы данных с помощью метода userRepository.findAll() и возвращает их в экземпляре ResponseEntity с кодом состояния HTTP 200 (ОК).
  • Метод createUser сохраняет нового пользователя в базе данных с помощью метода userRepository.save(user) и возвращает сохраненного пользователя в экземпляре ResponseEntity с кодом состояния HTTP 201 (СОЗДАНО).
  • Метод updateUser находит пользователя с предоставленным идентификатором, обновляет свойства электронной почты и пароля пользователя с помощью предоставленного экземпляра UserEntity и возвращает обновленного пользователя в экземпляре ResponseEntity с кодом состояния HTTP 201 (СОЗДАНО).
  • Метод getUser находит пользователя с предоставленным идентификатором и возвращает пользователя в экземпляре ResponseEntity с кодом состояния HTTP 200 (ОК).
  • Метод deleteUser удаляет пользователя с предоставленным идентификатором из базы данных с помощью метода userRepository.deleteById(id) и возвращает экземпляр ResponseEntity с кодом состояния HTTP 200 (ОК) в случае успеха или с кодом состояния HTTP 500 (ВНУТРЕННЯЯ ОШИБКА СЕРВЕРА), если произошло исключение. имеет место.

В целом, этот класс предоставляет набор методов для выполнения операций CRUD над сущностью UserEntity и возвращает результаты в экземпляре ResponseEntity с соответствующим кодом состояния HTTP.

Реализация UserController.java

package com.tutcoach.userapi.user;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("")
    public ResponseEntity<List<UserEntity>> getAllUsers() {
        return userService.getAllUsers();

    }


    @PostMapping("")
    public ResponseEntity<UserEntity> createUser(@RequestBody UserEntity user) {
        return userService.createUser(user);

    }

    @PutMapping("/{id}")
    public ResponseEntity<UserEntity> updateUser(@PathVariable("id") Long id, @RequestBody UserEntity user) {
        return userService.updateUser(id, user);

    }

    @GetMapping("/{id}")
    public ResponseEntity<UserEntity> getUser(@PathVariable("id") Long id) {
        return userService.getUser(id);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<UserEntity> deleteUser(@PathVariable("id") Long id) {
        return userService.deleteUser(id);
    }

}

Здесь у нас есть класс UserController.java, который определяет конечные точки для ресурса User в нашей веб-службе RESTful.

Наши конечные точки следующие.

  1. GET /users — возвращает список всех пользователей, хранящихся в базе данных.
  2. POST /users — создает новый пользовательский объект в базе данных с данными, переданными в теле запроса.
  3. PUT /users/{id} — обновляет существующий пользовательский объект с указанным id в базе данных с данными, переданными в теле запроса.
  4. GET /users/{id} — возвращает сущность пользователя с указанным id из базы данных.
  5. DELETE /users/{id} — Удаляет сущность пользователя с указанным id из базы данных

@RestController — это аннотация, которая помечает класс как контроллер RESTful, что означает, что он может обрабатывать HTTP-запросы и возвращать HTTP-ответы.

Позвольте мне объяснить каждый метод.

  1. getAllUsers() — этот метод обрабатывает HTTP-запрос GET к конечной точке /users и возвращает список всех пользователей, хранящихся в базе данных.
  2. createUser(@RequestBody UserEntity user) — этот метод обрабатывает HTTP-запрос POST к конечной точке /users и создает новый пользовательский объект в базе данных с данными, переданными в теле запроса.
  3. updateUser(@PathVariable("id") Long id, @RequestBody UserEntity user) — этот метод обрабатывает HTTP-запрос PUT к конечной точке /users/{id} и обновляет существующий пользовательский объект с указанным id в базе данных данными, переданными в теле запроса.
  4. getUser(@PathVariable("id") Long id) — этот метод обрабатывает HTTP-запрос GET к конечной точке /users/{id} и возвращает объект пользователя с указанным id из базы данных.
  5. deleteUser(@PathVariable("id") Long id) — этот метод обрабатывает HTTP-запрос DELETE к конечной точке /users/{id} и удаляет объект пользователя с указанным id из базы данных.

Аннотация @Autowired используется в UserService для внедрения зависимостей. Это означает, что Spring автоматически вставит экземпляр UserService в экземпляр UserController при создании UserController.

Класс ResponseEntity используется здесь для представления ответа HTTP, включая код состояния и тело ответа. Каждый метод в UserController возвращает объект ResponseEntity с соответствующим кодом состояния и телом ответа.

После завершения этого кода давайте скомпилируем и протестируем наши конечные точки. Чтобы протестировать нашу конечную точку, мы будем использовать REST-клиент бессонница.

Создать нового пользователя

Чтобы создать нового пользователя, мы отправляем запрос POST на конечную точку http://localhost:8080/users с телом запроса, как показано ниже в insomnia.

{
    "username": "johndoe",
    "password": "secret123",
    "email": "[email protected]"
}

Получить всех пользователей

Для запроса всех пользователей конечная точка API: http://localhost:8080/users and

  • Ответ: Возвращает список всех пользователей, хранящихся в базе данных.

Обновить пользователя

Чтобы обновить пользователя с помощью ID, нам нужно передать id в конечную точку API с данными полезной нагрузки в теле запроса. Обновление пользователя — это PUT запрос.

Получить информацию о пользователе

Чтобы получить сведения о пользователе, наша конечная точка API — HTTP://localhost:8080/users/id, как показано ниже.

Удалить пользователя

Чтобы удалить пользователя, нам нужно задать DELETE запрос на удаление конечной точки API http://localhost:8080/users/{id}, как показано ниже.

Заключение

В заключение мы создали CRUD API для объекта User, используя Spring Boot, Spring Data JPA и Postgresql. Мы реализовали конечные точки API для создания, чтения, обновления и удаления пользовательских данных. Мы также использовали библиотеку Lombok для сокращения шаблонного кода и класс ResponseEntity для возврата кодов ответов и сообщений HTTP.

Класс UserEntity определяет модель данных для пользовательского объекта, а интерфейс UserRepository предоставляет операции CRUD для пользовательского объекта. Класс UserService содержит бизнес-логику для пользовательской службы, а класс UserController сопоставляет конечные точки RESTful API с соответствующими методами службы.

В целом, этот CRUD API обеспечивает базовую основу для создания более сложных функций управления пользователями в приложении Spring Boot.