Введение: REST API на Java — это проще, чем кажется
Разработка REST API — один из самых востребованных навыков в современной backend-разработке. Java, благодаря своей надежности и огромной экосистеме, остается лидером для создания промышленных API. Многие новички считают, что написать REST API на Java сложно и долго. На самом деле, с правильным инструментом (Spring Boot) вы можете создать работающий сервис за 30 минут.
В этой статье мы на практике разберем, как быстро создать полноценный REST API на Java. Мы напишем небольшое приложение для управления списком книг, которое поддерживает стандартные CRUD-операции: создание, чтение, обновление и удаление записей. Весь код будет готов к запуску, а вы сможете протестировать его через Postman или браузер.
1. Подготовка проекта и настройка Spring Boot
Самый быстрый способ создать проект — использовать Spring Initializr. Это официальный генератор, который создает заготовку проекта с нужными зависимостями.
1.1. Генерация проекта
Перейдите на start.spring.io и выберите:
- Project: Maven (или Gradle)
- Language: Java
- Spring Boot: последняя стабильная версия (например, 3.2.x)
- Group: com.example
- Artifact: bookapi
Добавьте зависимости:
Spring Web— для создания REST-контроллеровSpring Data JPA— для работы с базой данныхH2 Database— встроенная база для тестов
Нажмите "Generate", скачайте архив и распакуйте его. Откройте проект в IntelliJ IDEA или любой другой IDE.
1.2. Структура проекта
После открытия проекта вы увидите следующую структуру:
bookapi/
├── src/
│ ├── main/
│ │ ├── java/com/example/bookapi/
│ │ │ ├── BookapiApplication.java
│ │ │ ├── controller/
│ │ │ ├── model/
│ │ │ └── repository/
│ │ └── resources/
│ │ └── application.properties
│ └── test/
└── pom.xml
Создайте пакеты controller, model и repository вручную — это облегчит навигацию.
2. Создание модели данных и репозитория
Начнем с модели — класса, который описывает сущность "Книга".
2.1. Класс Book (Model)
Создайте файл Book.java в пакете model:
package com.example.bookapi.model;
import jakarta.persistence.*;
@Entity
@Table(name = "books")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String author;
private int year;
public Book() {}
public Book(String title, String author, int year) {
this.title = title;
this.author = author;
this.year = year;
}
// Геттеры и сеттеры
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getAuthor() { return author; }
public void setAuthor(String author) { this.author = author; }
public int getYear() { return year; }
public void setYear(int year) { this.year = year; }
}
2.2. Репозиторий (Repository)
Создайте интерфейс BookRepository.java в пакете repository:
package com.example.bookapi.repository;
import com.example.bookapi.model.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
// Дополнительный метод: поиск по автору
List<Book> findByAuthor(String author);
}
JpaRepository уже содержит все базовые методы (save, findAll, findById, deleteById). Нам остается только их использовать.
3. Написание REST-контроллера
Теперь самое интересное — создадим контроллер, который будет обрабатывать HTTP-запросы.
3.1. Контроллер BookController
Создайте файл BookController.java в пакете controller:
package com.example.bookapi.controller;
import com.example.bookapi.model.Book;
import com.example.bookapi.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/api/books")
public class BookController {
@Autowired
private BookRepository bookRepository;
// GET: получить все книги
@GetMapping
public List<Book> getAllBooks() {
return bookRepository.findAll();
}
// GET: получить книгу по ID
@GetMapping("/{id}")
public ResponseEntity<Book> getBookById(@PathVariable Long id) {
Optional<Book> book = bookRepository.findById(id);
return book.map(ResponseEntity::ok)
.orElseGet(() -> ResponseEntity.notFound().build());
}
// POST: создать новую книгу
@PostMapping
public ResponseEntity<Book> createBook(@RequestBody Book book) {
Book savedBook = bookRepository.save(book);
return ResponseEntity.status(HttpStatus.CREATED).body(savedBook);
}
// PUT: обновить существующую книгу
@PutMapping("/{id}")
public ResponseEntity<Book> updateBook(@PathVariable Long id, @RequestBody Book bookDetails) {
Optional<Book> bookOptional = bookRepository.findById(id);
if (bookOptional.isPresent()) {
Book book = bookOptional.get();
book.setTitle(bookDetails.getTitle());
book.setAuthor(bookDetails.getAuthor());
book.setYear(bookDetails.getYear());
Book updatedBook = bookRepository.save(book);
return ResponseEntity.ok(updatedBook);
} else {
return ResponseEntity.notFound().build();
}
}
// DELETE: удалить книгу
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteBook(@PathVariable Long id) {
if (bookRepository.existsById(id)) {
bookRepository.deleteById(id);
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.notFound().build();
}
}
}
3.2. Настройка application.properties
Откройте файл application.properties и добавьте: