Архитектура Web-приложений
Архитектура современных приложений состоит из отдельных модулей, как показано на рисунке выше. Эти модули часто называют Frontend и Backend. Frontend – это модуль, который отвечает за юзер-интерфейс и логику, которые предоставляется приложением при использовании. Так, например когда мы заходим в соцсети через браузер, мы взаимодействуем именно с FrontEnd-модулем приложения. То, как отображаются наши посты в виде сторисов или карточек, сообщения и другие активности реализуются именно в FrontEnd-модуле. А все данные, которые мы видим, хранятся и обрабатываются в Backend или серверной части приложения. Эти модули обмениваются между собой посредством разных архитектурных стилей: REST, GRPC и форматов сообщений – JSON и XML.
В этой статье мы напишем примитивную серверную часть социальной сети с использованием Spring Boot, запустим свой сервер, рассмотрим разные типы HTTP запросов и их применение.
Необходимое требование к читателю: умение писать на Java и базовые знания Spring Framework. Данная статья познакомит вас со Spring Boot и даст базовые понятия данного фреймворка.
Инициализация проекта
Чтобы создать Spring Boot проект, перейдем на страницу https://start.spring.io/ и выберем необходимые зависимости: в нашем случае Spring Web. Чтобы запустить проект, необходима минимальная версия Java 17. Скачиваем проект и открываем в любом IDE (в моем случае – Intellij Idea)
Spring Web
– зависимость, которая предоставляет контейнер сервлетов Apache Tomcat (является дефолтным веб-сервером). Проще говоря, сервлеты – это классы, которые обрабатывают все входящие запросы.
Открываем проект и запускаем.
Мы видим, что проект запустился и готов обрабатывать запросы на порту 8080 – Tomcat started on port(s): 8080 (http)
.
Теперь создадим свой первый класс – GreetingController
. Controller-классы ответственны за обработку входящих запросов и возвращают ответ.
Чтобы сделать наш класс Controller
, достаточно прописать аннотацию @RestController
. @RequestMapping
указывает, по какому пути будет находиться определённый ресурс или выполняться логика.
Перезапускаем проект, и сервер готов уже обрабатывать наши запросы.
Открываем браузер по адресу http://localhost:8080/greet
и получаем следующий вывод.
Если отправить запрос по адресу http://localhost:8080/
, мы получим ошибку, т. к. по этому пути не определены логика обработки запроса и ресурсы.
Request Params
При отправке запросов мы часто используем переменные в запросе, чтобы передавать дополнительную информацию или же делать запросы гибкими. Параметр в запросе передаётся в конце адреса (=url
) сервера и указывается после вопросительного знака (=?
).
Например, http://localhost:8080/greet?name=Alice
. Параметр запроса является = name
cо значением = Alice
.
Чтобы обрабатывать переменную запроса, используется аннотация @RequestParam
. Параметры запроса могут быть опциональными или же обязательными. @RequestParam("name")
означает следующее: взять ту переменную из запроса, название которого равно name
.
Вдобавок, запрос может содержать несколько параметров.
Например, http://localhost:8080/greet/full?name=John&surname=Smith
. Параметры выделяются знаком &
. В этом запросе два параметра: name=John
и surname=Smith
.
Чтобы обработать каждый параметр запроса, нужно пометить каждую переменную @RequestParam
.
Path Variable
PathVariable
по применению похож на @Request Param
. @PathVariable
также является параметром запроса, но используются внутри адреса запроса. Например,
RequestParam
– http://localhost:8080/greet/full?name=John&surname=Smith
PathVariable
– http://localhost:8080/greet/John
. В этом случае John
является PathVariable.
В запросе можно указывать несколько PathVariable, как и в случае RequestParam
Чтобы протестировать, открываем браузер и переходим по адресам: http://localhost:8080/greet/John/Smith
и http://localhost:8080/greet/John
Запрос с двумя параметризованными PathVariable.
HTTP-методы
Когда мы говорим о запросах, мы также подразумеваем HTTP-метод, который используется при отправке этого запроса. Каждый запрос представляет собой некий HTTP-метод. Например, когда мы переходим в браузере по адресу http://localhost:8080/greet/John/Smith
, наш браузер отправляет GET-запрос на сервер.
Большая часть информационных систем обмениваются данными посредством HTTP-методов. Основными HTTP-методами являются – POST
, GET
, PUT
, DELETE
. Эти четыре запроса также называют CRUD-запросами.
- POST-метод – используется при создании новых ресурсов или данных. Например, когда мы загружаем новые посты в соцсетях, чаще всего используется POST-запросы. POST-запрос может иметь тело запроса.
- GET-метод – используется при получении данных. Например, при открытии любого веб-приложения, отправляется именно GET-запрос для получения данных и отображения их на странице. GET-запрос не имеет тела запроса.
- PUT-метод – используется для обновления данных, а также может иметь тело запроса, как и POST.
- DELETE-метод – используется для удаления данных.
Реализация основных методов
Давайте создадим сущности и реализуем методы, чтобы наш сервер принимал все четыре запроса. Для этого создадим сущности User
и Post
, и будем проводить операции над ними.
Для простоты User
имеет только два поля: username
и список постов posts
, а сущность Post
имеет поле description
и imageUrl
.
Сущность User
:
Сущность Post
:
Создаем новый класс контроллер – UserActivityController
, который будет обрабатывать наши запросы – POST, GET, PUT, DELETE.
Наш контроллер: UserActivityController.
Будем использовать список – List<User> users
в качестве локальной базы данных, где будем хранить все наши данные.
POST-запрос: добавление нового пользователя
Чтобы указать, что метод принимает POST-запросы используем аннотацию – @PostMapping
. Так как запрос имеет тело запроса, где мы передаем пользователя, нужно пометить переменную user
аннотацией @RequestBody
.
GET-запрос: получение пользователей
@Getmapping("")
указывает, что методы обрабатывают GET-запросы. Значение, которое передаётся внутри аннотации, является частью url или адреса. Например, запрос http://localhost:8080/users/baggio
обработается методом getUserByUsername()
, а запрос http://localhost:8080/users/
обработается методом http://localhost:8080/users
.
PUT-запрос: обновление данных
@PutMapping("/{username}")
указывает, что метод принимает PUT-запросы. В нашем примере в запросе мы передаем параметр запроса, а также тело запроса – post
. Метод принимает – username
, ищет юзера из списка с таким username
и добавляем новый пост к его списку постов.
Delete-запрос: удаление данных
@DeleteMapping("/{username}")
– указывает, что метод принимает DELETE-запросы.
Данный метод получает параметр username
из запроса и удаляет из списка пользователя с таким username.
Запуск приложения и тестирование
Чтобы убедиться, что все работает, мы можем отправить каждый вид запроса и протестировать. Для этого нам необходим API-client, который может посылать запросы. В примерах я использую POSTMAN.
Post-запрос: создание нового пользователя.
Тело запроса отправляется в виде JSON.
GET-запрос: получение пользователей
PUT-запрос: обновление списка постов пользователя
DELETE-запрос: удаление пользователя по username
В этой статье мы рассмотрели архитектуру современных web-приложений, а также написали свою серверную часть приложения, получив поверхностные знания по Spring Boot
, HTTP запросы
и параметры запросов.
Комментарии