Создание Spring Boot REST API с помощью Java - Полное руководство

Введение REST расшифровывается как REpresentational State Transfer, стандартизованный подход к созданию веб-сервисов. REST API - это промежуточный интерфейс программирования приложений, который позволяет двум приложениям взаимодействовать друг с другом через HTTP, подобно тому, как серверы обмениваются данными с браузерами. RESTful - наиболее распространенный подход к созданию веб-сервисов из-за того, что его легко изучать и создавать. Допустим, вы заказываете что-то в ресторане быстрого питания, и кассир запрашивает информацию.

Вступление

REST расшифровывается как REpresentational State Transfer , стандартизованный подход к созданию веб-сервисов.

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

RESTful - наиболее распространенный подход к созданию веб-сервисов из-за того, что его легко изучать и создавать.

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

В этом руководстве мы рассмотрим, как создать REST API на Java с помощью Spring Boot . Он будет принимать POST и GET для просмотра и добавления записей от объекта - User .

Требования

  • IDE или текстовый редактор
  • JDK 1.8 +
  • Maven 3+ или Gradle 4+ (в этой статье мы будем полагаться на Maven)

Инициализация проекта загрузки Spring

Использование Spring Initializr

Один простой способ инициализировать новый проект Spring Boot - использовать Spring Initializr , который автоматически генерирует для вас скелет проекта Spring Boot:

SpringInitializr{.ezlazyload}

Мы также добавим сюда несколько зависимостей, так как мы захотим использовать их в нашем проекте:

  • Spring Web - для включения Spring MVC и встроенного Tomcat в ваш проект.
  • Spring Data JPA - Java Persistence API и Hibernate
  • Spring Boot DevTools - очень полезные инструменты разработки
  • Драйвер MySQL - драйвер JDBC (может быть любая БД, которую вы хотите использовать)

После этого нажмите генерировать. Затем будет загружен zip-файл, содержащий созданный проект.

Использование Spring CLI

Если у вас установлен Spring CLI , вы можете выбрать использование консоли для создания базового проекта с помощью этой команды:

 spring init --build=maven -p=jar UserDemo 

Примечание. Spring CLI напрямую вызывает Spring Initializr для выполнения этой операции. Оба варианта создают один и тот же проект.

После создания базового проекта загрузите и импортируйте его в IDE или текстовый редактор по выбору. Если вы хотите собрать, скомпилировать и запустить свое приложение через IDE, убедитесь, что вы импортировали его как проект Maven или Gradle .

После импорта сгенерированный базовый pom.xml в вашем проекте будет выглядеть так:

 <!-- Project information--> 
 <dependencies> 
 <dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-data-jpa</artifactId> 
 </dependency> 
 <dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-web</artifactId> 
 </dependency> 
 <dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-devtools</artifactId> 
 <scope>runtime</scope> 
 <optional>true</optional> 
 </dependency> 
 <dependency> 
 <groupId>mysql</groupId> 
 <artifactId>mysql-connector-java</artifactId> 
 </dependency> 
 <dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-test</artifactId> 
 <scope>test</scope> 
 <exclusions> 
 <exclusion> 
 <groupId>org.junit.vintage</groupId> 
 <artifactId>junit-vintage-engine</artifactId> 
 </exclusion> 
 </exclusions> 
 </dependency> 
 </dependencies> 
 <!-- Build information --> 

Все сделанные вами настройки будут отражены в этом файле. Кроме того, автоматически настраиваются зависимости по умолчанию, базовый снимок 0.0.1-SNAPSHOT и плагин сборки Maven.

Для справки: если вы хотите создать проект Gradle , ваш build.gradle будет выглядеть так:

 plugins { 
 id 'org.springframework.boot' version '2.3.5.RELEASE' 
 id 'io.spring.dependency-management' version '1.0.10.RELEASE' 
 id 'java' 
 } 
 
 group = 'com.howto' 
 version = '0.0.1-SNAPSHOT' 
 sourceCompatibility = '11' 
 
 repositories { 
 mavenCentral() 
 } 
 
 dependencies { 
 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 
 implementation 'org.springframework.boot:spring-boot-starter-web' 
 developmentOnly 'org.springframework.boot:spring-boot-devtools' 
 runtimeOnly 'com.mysql:mysql-connector-java' 
 testImplementation('org.springframework.boot:spring-boot-starter-test') { 
 exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 
 } 
 } 
 
 test { 
 useJUnitPlatform() 
 } 

Подключение Spring Boot к базе данных

Далее, прежде чем мы начнем работать над приложением, нам нужно настроить базу данных. Это легко сделать с помощью Spring Data JPA, который позволяет нам установить это соединение всего с парой параметров.

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

Чтобы сообщить Spring, как подключиться к предпочитаемой вами базе данных, в application.properties вам необходимо добавить некоторую элементарную информацию:

 spring.datasource.url = jdbc:mysql://localhost:3306/user 
 spring.datasource.username = user 
 spring.datasource.password = user 
 spring.jpa.hibernate.ddl-auto = update 
 spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect 

Здесь мы установили datasource.url на наш URL-адрес подключения JDBC. Это зависит от вашей базы данных. Мы предоставили username и password необходимые для аутентификации в этой базе данных, а также установили для ddl-auto значение update . Свойство jpa.hibernate.ddl-auto напрямую влияет на hibernate.hbm2ddl.auto и по существу определяет, как Hibernate должен обрабатывать управление инструментами схемы.

Для производственных приложений это значение обычно установлено равным « none , так как специальный персонал управляет поведением. В разработке чаще всего используется update , позволяющее обновлять схему каждый раз при перезапуске приложения, что обеспечивает гибкость при работе над разработкой.

Наконец, мы установили свойство hibernate.dialect Hibernate имеет разные диалекты для разных баз данных. Он может автоматически устанавливать диалект в зависимости от вашей конфигурации, хотя для дополнительной безопасности всегда рекомендуется указывать его явно.

Модель домена - Создание модели пользователя

Теперь, когда соединение с базой данных установлено и работает, мы можем перейти к модели предметной области . Это набор классов или, скорее, моделей , которые мы будем использовать в нашем приложении. В Hibernate они также называются Entities , а также аннотируются аннотацией @Entity

Каждый @Entity Hibernate, для него создается таблица, отображаются поля, и он становится управляемым объектом для базы данных, которую вы настроили.

Во-первых, давайте создадим простую сущность User Мы добавим к классу @Entity и необязательную @Table чтобы указать имя нашей таблицы.

Если не установлен, он просто будет использовать то же имя, что и класс:

 @Entity 
 @Table(name = "user") 
 public class User { 
 @Id 
 @GeneratedValue(strategy = GenerationType.AUTO) 
 private long id; 
 private String name; 
 
 // Constructor, getters and setters 
 } 

Чтобы аннотировать поле как id объекта, вы используете @Id , и она будет установлена как автоматически увеличивающийся первичный ключ таблицы. Кроме того, вы можете дополнительно установить, что это @GeneratedValue и установить для GenerationType значение AUTO .

Это настройка по умолчанию, если вы опустите аннотацию @GeneratedValue Вы также можете установить другие значения: IDENTITY , SEQUENCE и TABLE . Они требуют отдельной статьи о Hibernate.

Кроме того, вы можете установить @Column для каждого из полей, указав имя для каждого из них, если вы хотите настраиваемые имена - @Column(name = "user_id") , сохранит поле id user_id а не просто id .

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

Этот класс (объект) теперь зарегистрирован в Hibernate. Если мы запустим приложение, учитывая нашу ddl-auto , таблица отобразится в вашей соответствующей базе данных с правильной таблицей и сопоставлениями для типов данных.

Уровень сохраняемости - создание классов репозитория

Далее поработаем над слоем постоянства. Нам понадобится UserRepository для выполнения операций CRUD с нашими объектами User Для этого мы укажем интерфейс, расширяющий CrudRepository , и аннотируем его с помощью @Repository .

@Repository - это вариант @Component , которая сообщает Spring, что это компонент, которым должен управлять контейнер IoC. В частности, репозитории предназначены для определения логики уровня сохраняемости.

CrudRepository CrudRepository принимает класс сущности, а также id он должен использовать для запроса:

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

CrudRepository объявляет такие методы, как findAll() , findOne() и save() которые составляют базовую функциональность CRUD репозитория. Вы можете использовать этот UserRepository как есть, чтобы выполнять операции CRUD с User , без дополнительной настройки.

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

Бизнес-уровень - Создание контроллера

Наконец, мы дошли до бизнес-уровня, где мы реализуем фактическую бизнес-логику обработки информации и используем компоненты уровня сохраняемости вместе с моделью домена для хранения данных.

Давайте создадим контроллер, @RestController его как @RestController, поскольку мы создаем REST API, и добавим к нему @RequestMapping @RestController - это просто комбинация @Controller и @ResponseBody , что означает, что вместо рендеринга страниц он просто ответит данными, которые мы ему предоставили. Это естественно для REST API - возврат информации после попадания в конечную точку API.

Если вы хотите узнать больше о @RequestMapping и его производных вариантах , у нас есть отличная статья, посвященная именно этой теме!

Давайте продолжим и UserController :

 @RestController 
 @RequestMapping("/api/user") 
 public class UserController { 
 
 @Autowired 
 private UserRepository userRepository; 
 
 @GetMapping 
 public List<User> findAllUsers() { 
 // Implement 
 } 
 
 @GetMapping("/{id}") 
 public ResponseEntity<User> findUserById(@PathVariable(value = "id") long id) { 
 // Implement 
 } 
 
 @PostMapping 
 public User saveUser(@Validated @RequestBody User user) { 
 // Implement 
 } 
 } 

Мы @Autowired наш UserRepository . Он используется для внедрения зависимостей, поскольку класс репозитория здесь является зависимостью. Если вы хотите узнать больше об аннотациях Core Spring Framework , ознакомьтесь с нашим руководством!

Мы также использовали @GetMapping и @PostMapping чтобы указать, какие типы HTTP-запросов принимают и обрабатывают наши методы. Это производные варианты аннотации @RequestMapping method = RequestMethod.METHOD для соответствующих типов.

Начнем с реализации конечной точки findAll()

 @GetMapping 
 public List<User> findAllUsers() { 
 return userRepository.findAll(); 
 } 

Этот метод просто вызывает userRepository для findAll() пользователей и возвращает список в качестве ответа.

Затем давайте реализуем конечную точку, чтобы получить каждого пользователя по их id :

 @GetMapping("/{id}") 
 public ResponseEntity<User> findUserById(@PathVariable(value = "id") long id) { 
 Optional<User> user = userRepository.findById(id); 
 
 if(user.isPresent()) { 
 return ResponseEntity.ok().body(user.get()); 
 } else { 
 return ResponseEntity.notFound().build(); 
 } 
 } 

Объект с данным id может отсутствовать в базе данных, поэтому мы помещаем возвращенного User в Optional . Если вы хотите узнать больше о Optional в Java 8 , у нас есть подробное руководство!

Затем, если используется user.isPresent() , мы возвращаем HTTP-ответ 200 OK user экземпляр в качестве тела ответа. В противном случае мы возвращаем ResponseEntity.notFound() .

Наконец, давайте создадим конечную точку для спасения пользователей:

 @PostMapping 
 public User saveUser(@Validated @RequestBody User user) { 
 return userRepository.save(user); 
 } 

Метод save() из пользовательского репозитория сохраняет нового пользователя, если он еще не существует. Если пользователь с данным id уже существует, генерируется исключение. В случае успеха он возвращает постоянного пользователя.

@Validated является валидатором для данных, которые мы предоставляем о пользователе, и обеспечивает базовую достоверность. Если информация о пользователе недействительна, данные не сохраняются. Кроме того, @RequestBody сопоставляет тело POST отправленного в конечную точку, с User мы хотели бы сохранить.

Если вы хотите узнать больше о получении тела HTTP в Spring Boot , мы вам поможем!

Теперь пора запустить приложение и проверить, работает ли оно.

Компиляция, сборка и запуск

Порт по умолчанию, на котором работает Spring Boot, - 8080 . Если вы хотите изменить порт по какой-либо причине, вы можете настроить его в своем файле application.properties

 server.port = 9090 

Если у вас есть IDE, такая как IntelliJ, которая имеет обширную поддержку для запуска проектов Spring Boot, вы можете продолжить и запустить ее таким образом.

Если нет, мы будем использовать командную строку для запуска нашего проекта. Мы можем запустить приложение напрямую, выполнив ./mvnw spring-boot:run (или ./gradlew bootRun если вы используете Gradle ) в командной строке из папки вашего базового проекта, где находится pom.xml

Другой вариант - упаковать ваше приложение в jar и запустить его таким образом.

Для этого нам просто нужно выполнить ./mvnw clean package ./mvnw ( .gradlew build в Gradle) и запустить файл jar, выполнив эту команду:

 $ java -jar target/DemoUser-0.0.1-SNAPSHOT.jar 

Если вы используете Gradle, путь к файлу jar будет другим:

 $ java -jar build/libs/DemoUser-0.0.1-SNAPSHOT.jar 

Вы узнаете, когда ваше приложение успешно запустилось, если увидите эти журналы аудита в конце командной строки:

 2020-11-05 13:27:05.073 INFO 21796 --- [ restartedMain] osbdaOptionalLiveReloadServer : LiveReload server is running on port 35729 
 2020-11-05 13:27:05.108 INFO 21796 --- [ restartedMain] osbwembedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 
 2020-11-05 13:27:05.121 INFO 21796 --- [ restartedMain] com.howto.DemoUser.DemoUserApplication : Started DemoUserApplication in 1.765 seconds (JVM running for 2.236) 

Тестирование API

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

Для GET мы можем использовать браузеры, curl или Postman - все, что вам удобнее.

Давайте поразим конечную точку http://localhost:8080/api/user с помощью запроса GET

 $ curl http://localhost:8080/api/user 

Или в адресной строке браузера перейдите по http://localhost:8080/api/user , и ваш браузер отобразит ответ JSON:

 [ 
 { 
 "id": 1, 
 "name":"John" 
 }, 
 { 
 "id": 2, 
 "name":"Jane" 
 }, 
 { 
 "id": 3, 
 "name": "Juan" 
 } 
 ] 

Мы можем изменить этот URL, чтобы включить параметр пути, id чтобы получить конкретного пользователя. Отправим HTTP-запрос GET на http://localhost:8080/api/user/3 :

 { 
 "id": 3, 
 "name": "Juan" 
 } 

Наконец, давайте отправим запрос HTTP POST и добавим пользователя в нашу базу данных, предоставив данные, необходимые в нашей модели. Поля в полезной нагрузке JSON должны совпадать с именами полей в нашей БД / модели:

 $ curl --location --request POST 'http://localhost:8080/api/user' \ 
 --header 'Content-Type: application/json' \ 
 --data-raw '{ "id": 4, "name": "Jason" }' 

API вернет 200 в качестве ответа с этим в качестве тела ответа постоянного пользователя:

 { 
 "id": 4, 
 "name": "Jason" 
 } 

Заключение

Вот и все. Вы успешно создали свой собственный Spring Boot REST API!

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

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

comments powered by Disqus