Что такое rest контроллер

REST API с использованием Spring Security и JWT

Рано или поздно каждый Java-разработчик столкнется с необходимостью реализовать защищенное REST API приложение. В этой статье хочу поделиться своей реализацией этой задачи.

1. Что такое REST?

REST (от англ. Representational State Transfer — «передача состояния представления») – это общие принципы организации взаимодействия приложения/сайта с сервером посредством протокола HTTP.

Диаграмма ниже показывает общую модель.

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Всё взаимодействие с сервером сводится к 4 операциям (4 — это необходимый и достаточный минимум, в конкретной реализации типов операций может быть больше):

Получение данных с сервера (обычно в формате JSON, или XML);

Добавление новых данных на сервер;

Модификация существующих данных на сервере;

Удаление данных на сервере

Более подробно можно прочесть в остальных источниках, статей о REST много.

2. Задача

Необходимо подготовить защищенное REST приложение, доступ к которому может быть осуществлен только для авторизованного пользователя. Авторизация с передачей логина и пароля выполняется отдельным запросом, при успешной авторизации система должна сгенерировать и вернуть токен. Валидация остальных запросов должна быть осуществлена по токену.
Схема нашего приложения будет выглядеть следующим образом:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

3. Технологии

Для решения используем фреймворк Spring Boot и Spring Web, для него требуется:

Авторизация и валидация будет выполнена силами Spring Security и JsonWebToken (JWT).
Для уменьшения кода использую Lombok.

4. Создание приложения

Переходим к практике. Создаем Spring Boot приложение и реализуем простое REST API для получения данных пользователя и списка пользователей.

4.1 Создание Web-проекта

Создаем Maven-проект SpringBootSecurityRest. При инициализации, если вы это делаете через Intellij IDEA, добавьте Spring Boot DevTools, Lombok и Spring Web, иначе добавьте зависимости отдельно в pom-файле.

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

4.2 Конфигурация pom-xml

После развертывания проекта pom-файл должен выглядеть следующим образом:

Должен быть указан parent-сегмент с подключенным spring-boot-starter-parent;

И установлены зависимости spring-boot-starter-web, spring-boot-devtools и Lombok.

4.3 Создание ресурса REST

Разделим все классы на слои, создадим в папке com.springbootsecurityrest четыре новые папки:

model – для хранения POJO-классов;

repository – в полноценных проектах используется для взаимодействия с БД, но т.к. у нас ее нет, то он будет содержать список пользователей;

service – слой сервиса, прослойка между контролером и слоем ресурсов, используется для получения данных из ресурса, их проверки и преобразования (если это необходимо);

rest – будет содержать в себе классы контроллеры.

В папке model создаем POJO класс User.

В папке repository создаём класс UserRepository c двумя методами:

getByLogin – который будет возвращать пользователя по логину;

getAll – который будет возвращать список всех доступных пользователей. Чтобы Spring создал бин на основании этого класса, устанавливаем ему аннотацию @Repository.

В папке service создаем класс UserService. Устанавливаем классу аннотацию @Service и добавляем инъекцию бина UserRepository. В класс добавляем метод getAll, который будет возвращать всех пользователей и getByLogin для получения одного пользователя по логину.

Создаем контроллер UserController в папке rest, добавляем ему инъекцию UserService и создаем один метод getAll. С помощью аннотации @GetMapping указываем адрес контроллера, по которому он будет доступен клиенту и тип возвращаемых данных.

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

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

5. Spring Security

Простенькое REST API написано и пока оно открыто для всех. Двигаемся дальше, теперь его необходимо защитить, а доступ открыть только авторизованным пользователям. Для этого воспользуемся Spring Security и JWT.

Spring Security это Java/JavaEE framework, предоставляющий механизмы построения систем аутентификации и авторизации, а также другие возможности обеспечения безопасности для корпоративных приложений, созданных с помощью Spring Framework.

JSON Web Token (JWT) — это открытый стандарт (RFC 7519) для создания токенов доступа, основанный на формате JSON. Как правило, используется для передачи данных для аутентификации в клиент-серверных приложениях. Токены создаются сервером, подписываются секретным ключом и передаются клиенту, который в дальнейшем использует данный токен для подтверждения своей личности.

5.1 Подключаем зависимости

Добавляем новые зависимости в pom-файл.

5.2 Генерация и хранения токена

Начнем с генерации и хранения токена, для этого создадим папку security и в ней создаем класс JwtTokenRepository с имплементацией интерфейса CsrfTokenRepository (из пакета org.springframework.security.web.csrf).

Интерфейс указывает на необходимость реализовать три метода:

Генерация токена в методе generateToken;

Сохранения токена – saveToken;

Получение токена – loadToken.

Генерируем токен силами Jwt, пример реализации метода.

Параметр secret является ключом, необходимым для расшифровки токена, оно может быть постоянным для всех токенов, но лучше сделать его уникальным только для пользователя, например для этого можно использовать ip-пользователя или его логин. Дата exp является датой окончания токена, рассчитывается как текущая дата плюс 30 минут. Такой параметр как продолжительность жизни токена рекомендую вынести в application.properties.

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

Сохранение токена выполняем в response (ответ от сервера) в раздел headers и открываем параметр для чтения фронта указав имя параметра в Access-Control-Expose-Headers.

Добавляем к классу еще один метод по очистке токена из response, будем использовать его при ошибке авторизации.

5.3 Создание нового фильтра для SpringSecurity

Создаем новый класс JwtCsrfFilter, который является реализацией абстрактного класса OncePerRequestFilter (пакет org.springframework.web.filter). Класс будет выполнять валидацию токена и инициировать создание нового. Если обрабатываемый запрос относится к авторизации (путь /auth/login), то логика не выполняется и запрос отправляется далее для выполнения базовой авторизации.

5.4 Реализация сервиса поиска пользователя

Теперь необходимо подготовить сервис для поиска пользователя по логину, которого будем авторизовывать. Для этого нам необходимо добавить к сервису UserService интерфейс UserDetailsService из пакета org.springframework.security.core.userdetails. Интерфейс требует реализовать один метод, выносить его в отдельный класс нет необходимости.

Полученного пользователя необходимо преобразовать в класс с реализацией интерфейса UserDetails или воспользоваться уже готовой реализацией из пакета org.springframework.security.core.userdetails. Последним параметром конструктора необходимо добавить список элементов GrantedAuthority, это роли пользователя, у нас их нет, оставим его пустым. Если пользователя по логину не нашли, то бросаем исключение UsernameNotFoundException.

5.5 Обработка авторизации

По результату успешно выполненной авторизации возвращаю данные авторизованного пользователя. Для этого создадим еще один контроллер AuthController с методом getAuthUser. Контроллер будет обрабатывать запрос /auth/login, а именно обращаться к контексту Security для получения логина авторизованного пользователя, по нему получать данные пользователя из сервиса UserService и возвращать их на фронт.

5.6 Обработка ошибок

Что бы видеть ошибки авторизации или валидации токена, необходимо подготовить обработчик ошибок. Для этого создаем новый класс GlobalExceptionHandler в корне com.springbootsecurityrest, который является расширением класса ResponseEntityExceptionHandler с реализацией метода handleAuthenticationException.

Метод будет устанавливать статус ответа 401 (UNAUTHORIZED) и возвращать сообщение в формате ErrorInfo.

5.7 Настройка конфигурационного файла Spring Security.

Все данные подготовили и теперь необходимо настроить конфигурационный файл. В папке com.springbootsecurityrest создаем файл SpringSecurityConfig, который является реализацией абстрактного класса WebSecurityConfigurerAdapter пакета org.springframework.security.config.annotation.web.configuration. Помечаем класс двумя аннотациями: Configuration и EnableWebSecurity.

Реализуем метод configure(AuthenticationManagerBuilder auth), в класс AuthenticationManagerBuilder устанавливаем сервис UserService, для того что бы Spring Security при выполнении базовой авторизации мог получить из репозитория данные пользователя по логину.

Реализуем метод configure(HttpSecurity http):

Разберем метод детальнее:

.authorizeRequests().antMatchers(«/auth/login»).authenticated() для запроса /auth/login выполняем авторизацию силами security. Что бы не было двойной валидации (по токену и базовой), запрос был добавлен в исключение к классу JwtCsrfFilter;

6. Проверка функционала

Для проверки использую Postman. Запускаем бэкенд и выполняем запрос http://localhost:8080/users с типом GET.

Токена нет, валидация не пройдена, получаем сообщение с 401 статусом.

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Пытаемся авторизоваться с неверными данными, выполняем запрос http://localhost:8080/auth/login с типом POST, валидация не выполнена, токен не получен, вернулась ошибка с 401 статусом.

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Авторизуемся с корректными данными, авторизация выполнена, получен авторизованный пользователь и токен.

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

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

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Заключение

В этой статье рассмотрели один из примеров реализации REST приложения с Spring Security и JWT. Надеюсь данный вариант реализации кому то окажется полезным.

Источник

Подготовка к Spring Professional Certification. Spring REST

Сегодняшняя статья рассмотрит основные вопросы про REST в Spring. Она будет особенно полезна для начинающих программистов.

Официальный гид от Pivotal, в котором написано про темы для подготовки.

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Spring REST — это часть Spring MVC. Поэтому многое из Spring MVC будет применяться в REST и наоборот. Для более подробного ознакомления со Spring MVC можно прочитать эту статью.

Чтобы понять концепцию REST, нужно разобрать акроним на его составляющие:

REST это передача состояний ресурса между сервером и клиентом.

Ресурс в REST — это все, что может быть передано между клиентом и сервером.
Вот несколько примеров ресурсов:

Самые часто-используемые обозначаются аббревиатурой CRUD:

По умолчанию REST не защищен.

Вы можете настроить безопасность с помощью Basic Auth, JWT, OAuth2

Это операции, которые не модифицируют ресурсы. Вот их список:

Идемпотентые методы — это методы, при каждом вызове которых результат будет одинаковый.

То есть, результат после 1 вызова такого метода будет такой же, как и результат после 10 вызовов этого метода.

Это важно для отказоустойчевого API. Предположим, что клиент хочет обновить ресурс с помощью POST-запроса? Если POST не идемпотентный метод, то при многократном вызове возникнут непредвиденные обновления ресурса. Используя идемпотентные методы, вы ограждаете себя от многих ошибок.

Да. REST хорошо масштабируется потому что он не хранит состояние.

Это значит что он не хранит информацию о пользовательских сессиях на сервере.

Информация о клиенте не должна хранится на стороне сервера, а должна передаваться каждый раз туда, где она нужна. Вот что значит ST в REST, State Transfer. Вы передаете состояние, а не храните его на сервере.

REST также интероперабельный — это значит, что на нем могут взаимодействовать разные программы написанные на разных языках. Это исходит из 2ух факторов:

HttpMessageConverter конвертирует запрос в объект и наоборот.

Spring имеет несколько реализаций этого интерфейса, а вы можете создать свою.

В этом случае DispatcherServlet не использует Model и View.

В REST вообще не существует Model и View. Есть только данные, поставляемые контроллером, и представление ресурса, когда сообщение конвертируется из медиа-типа(json, xml. ) в объект.

BufferedImageHttpMessageConverter — конвертирует BufferedImage в(из) код изображения.

Jaxb2RootElementHttpMessageConverter — конвертирует xml в(из) объект, помеченный jaxb2 аннотациями. Регистрируется, если jaxb2 находится в classpath.

MappingJackson2HttpMessageConverter — конвертирует JSON в(из) объект. Регистрируется, если Jackson 2 находится в classpath.

StringHttpMessageConverter — конвертирует все медиа-файлы в text/plain.

Теперь она используется только для указания URI до класса-контроллера.

Это более узкие аннотации для маппинга http-методов.

Все написанное ниже характерно также и для других аннотаций.

Аннотация @GetMapping — это просто аннотация которая содержит @RequestMapping(method = RequestMethod.GET).
Она также позволяет более глубоко настроить метод-обработчик.
Ее параметры(они конвертируются в аналогичные параметры @RequestMapping):

consumes — тип принимаемых данных. Используется в REST

По умолчанию аннотация принимает путь до метода.
@GetMapping(«managers») = @GetMapping(path = «managers»)

Эта аннотация используется для того, чтобы методы обработчики могли получить параметры из http-запроса.

Эта аннотация получает определенную часть из URI.

POST — 200 OK, 201 Created, 204 No Content

PUT — 200 OK, 201 Created, 204 No Content

DELETE — 204 No Content, 202 Accepted

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

Вместо использования аннотации можно возвращать ResponseEntity и вручную устанавливать код ответа.

Не рекомендуется использовать ResponseEntity и @ReponseStatus вместе.

Это специальный класс, который представляет http-ответ. Он содержит тело ответа, код состояния, заголовки. Мы можем использовать его для более тонкой настройки http-ответа.

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

Вы можете использовать аннотацию @RequestBody на параметре метода, для того чтобы тело запроса конвертировалось в этот параметр.

RestTemplate это специальный клиент в Spring для отправки http-запросов. Он предоставляет удобные API для легкого вызова конечных точек REST’а в одну строку.

Более подробно об использовании можно узнать в этой статье.

Источник

Контроллеры ¶

После создания классов ресурсов и настройки способа форматирования ресурсных данных следующим шагом является создание действий контроллеров для предоставления ресурсов конечным пользователям через RESTful API.

В Yii есть два базовых класса контроллеров для упрощения вашей работы по созданию RESTful-действий: yii\rest\Controller и yii\rest\ActiveController. Разница между этими двумя контроллерами в том, что у последнего есть набор действий по умолчанию, который специально создан для работы с ресурсами, представленными Active Record. Так что если вы используете Active Record и вас устраивает предоставленный набор встроенных действий, вы можете унаследовать классы ваших контроллеров от yii\rest\ActiveController, что позволит вам создать полноценные RESTful API, написав минимум кода.

yii\rest\Controller и yii\rest\ActiveController имеют следующие возможности, некоторые из которых будут подробно описаны в следующих разделах:

yii\rest\ActiveController, кроме того, предоставляет следующие возможности:

Создание классов контроллеров ¶

Создание нового действия похоже на создание действия для Web-приложения. Единственное отличие в том, что в RESTful-действиях вместо рендера результата в представлении с помощью вызова метода render() вы просто возвращаете данные. Выполнение преобразования исходных данных в запрошенный формат ложится на сериализатор и объект ответа. Например:

Фильтры ¶

Большинство возможностей RESTful API, предоставляемых yii\rest\Controller, реализовано на основе фильтров. В частности, следующие фильтры будут выполняться в том порядке, в котором они перечислены:

Эти именованные фильтры объявлены в методе behaviors(). Вы можете переопределить этот метод для настройки отдельных фильтров, отключения каких-либо из них или для добавления ваших собственных фильтров. Например, если вы хотите использовать только базовую HTTP-аутентификацию, вы можете написать такой код:

Наследование от ActiveController ¶

Если ваш класс контроллера наследуется от yii\rest\ActiveController, вам следует установить значение его свойства modelClass равным имени класса ресурса, который вы планируете обслуживать с помощью этого контроллера. Класс ресурса должен быть унаследован от yii\db\ActiveRecord.

Настройка действий ¶

По умолчанию yii\rest\ActiveController предоставляет набор из следующих действий:

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

Выполнение контроля доступа ¶

При предоставлении ресурсов через RESTful API часто бывает нужно проверять, имеет ли текущий пользователь разрешение на доступ к запрошенному ресурсу (или ресурсам) и манипуляцию им (или ими). Для yii\rest\ActiveController эта задача может быть решена переопределением метода checkAccess() следующим образом:

Метод checkAccess() будет вызван действиями по умолчанию контроллера yii\rest\ActiveController. Если вы создаёте новые действия и хотите в них выполнять контроль доступа, вы должны вызвать этот метод явно в своих новых действиях.

Подсказка: вы можете реализовать метод checkAccess() с помощью «Контроля доступа на основе ролей» (RBAC).

Источник

REST на примере Spring MVC

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

Шаг 0. Что такое Web Service?

Web Service (Веб служба) – это технология позволяющая предоставлять общий доступ к определённым данным системы.

Существует несколько видов Web Service (в дальнейшем WS), но мы будем рассматривать в этом уроке только один из них, а именно WS REST.

REST (Representational State Transfer), «передача состояния представления» — стиль построения архитектуры распределенного приложения. Был описан и популяризован в 2000 году Роем Филдингом (Roy Fielding), одним из создателей протокола HTTP. Самой известной системой, построенной в значительной степени по архитектуре REST, является современная Всемирная паутина.

Такое разъяснение WS REST дает Википедия, но если чесно, то мне слабо понятно что это из выше указанного термина.

Если своими словами, то REST – это технология, которая обеспечит возможность предоставление доступа к данным внешним системам, а также она описывает набор правил, которые нужно соблюдать, чтобы реализовать WS REST.

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

Задача

Любая работа программиста состоит с составления задачи, которую он должен решить. Наша задача следуящая:

– Реализовать WS REST и протестировать его в боевых условиях с помощью тестового приложения.

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Шаг 1. Создание проекта и подключение зависимостей

Создаем Maven проект называем его SpringRESTExam:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Теперь давайте подключим зависимости, так как мы будем реализовывать REST с помощью Spring Framework, то нам потребуются следующие зависимости:

Мы подключили две зависимости, первая это Spring MVC, вторая это поддержка Servlet API.

Еще для удобства я использую следующие два плагина:

Первый плагимы говорит о том, что проект будет компилироваться Java 7, а второй конфигурирует сборку war архива и говорит, что мы не требуемся в использовании web.xml файла.

Шаг 2. Создание сущности

Для того чтобы продемонстрировать REST в котором мы будем манипулировать данными мы создадим объект MyDataObject в который добавим все необходимые для наших целей поля.

Я предпочел хранить в этом объекте время и сообщение.

И так что же нам надо сделать?

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Мы создадим веб-страницу на которой будет 4 кнопки, которые будут демонстрировать 4 метода протокола HTTP.

Шаг 3. Конфигурирование Spring

Прежде чем преступить к созданию REST нам нужно сконфигурировать Spring, это не сложно.

Для начало создадим класс WebAppConfig:

Теперь нужно зарегистрировать эту конфигурацию в Spring Context, для этого создадим еще один класс Initializer:

Теперь можно приступать к созданию REST сервиса.

Шаг 4. Создание REST сервиса

Возможно вам уже приходилось работать с API, любым. Так вот мы сейчас с помощью REST создадим свой маленький API.

В виде REST сервиса будет выступать Spring Controller, поэтому создаем MainController:

Данные REST не выполняет действий с БД либо другими WS он просто имитирует работу REST.

Значит в результате у нас будет одна ссылка:

http://localhost:8080/myservice – обращаясь по этой ссылке разными HTTP методами можно выполнять разные действия.

Например:

http://localhost:8080/myservice/101245648 (GET) – числа, это время в милисекундах.

http://localhost:8080/myservice (PUT) – но HTTP запрос должен содержать объект (ниже будет пример).

http://localhost:8080/myservice (POST) – позволит получить готовый объект.

http://localhost:8080/myservice/101245648 (DELETE) – позволит удалить объект по времени например.

Как вы видите обращаясь по одной и той же ссылке мы выполняем разные действия.

Шаг 5. Создаем веб-страницу для проверки нашего WS REST

Для этого я решил в этом же проекте создать простую JSP страницу в папке /pages/ назвал её index.jsp и в ней с помощью JQuery и технологии Ajax выполняю запросы к нашему WS.

Выглядеть эта страничка будет следующим образом:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Шаг 6. Деплоим и тестируем

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Теперь запускам Tomcat либо в моём случае Glassfish4 и деплоим:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

На этом все 🙂 Возникнут вопросы, задавайте их в коментариях.

Источник

Руководство по REST архитектуре

Руководство по REST архитектуре

Часть 1. Что такое REST

REST, как и многое в мире IT, — это акроним, сокращение от английского Representational State Transfer — передача состояния представления. Это архитектурный стиль взаимодействия компонентов распределенной системы в компьютерной сети. Проще говоря, REST определяет стиль взаимодействия (обмена данными) между разными компонентами системы, каждая из которых может физически располагаться в разных местах. Данный архитектурный стиль представляет собой согласованный набор ограничений, учитываемых при проектировании распределенной системы. Эти ограничения иногда называют принципами REST. Их немного, всего 6 штук. О них мы поговорим чуть позже.

История возникновения REST

Термин REST ввел Рой Филдинг, один из создателей протокола HTTP, в своей докторской диссертации «Архитектурные стили и дизайн сетевых программных архитектур» («Architectural Styles and the Design of Network-based Software Architectures») в 2000 году. Можно сказать, что термин REST еще молодой, хотя его концепция лежит в самой основе всемирной паутины. Мы не будем погружаться глубоко в историю возникновения данного термина. Если хочешь окунуться в первоисточники, загляни в диссертацию Филдинга.

REST ограничения и принципы

Как было сказано выше, REST определяет, как компоненты распределенной системы должны взаимодействовать друг с другом. В общем случае этот происходит посредством запросов-ответов. Компоненту, которая отправляет запрос называют клиентом; компоненту, которая обрабатывает запрос и отправляет клиенту ответ, называют сервером. Запросы и ответы, чаще всего, отправляются по протоколу HTTP (англ. HyperText Transfer Protocol — «протокол передачи гипертекста»). Как правило сервер — это некое веб-приложение. Клиентом же может быть не то чтобы что угодно, но довольно многое. Например, мобильное приложение, которое запрашивает у сервера данные. Либо браузер, который отправляет запросы с веб-страницы на сервер для загрузки данных. Приложение А может запрашивать данные у приложения Б. Тогда А является клиентом по отношению к Б, а Б — сервером по отношению к А. Одновременно с этим, А может обрабатывать запросы от В, Г, Д и т.д. В таком случае, приложение А является одновременно и сервером, и клиентом. Все зависит от контекста. Однозначно одно: компонента которая шлет запрос — это клиент. Компонента, которая принимает, обрабатывает и отвечает на запрос — сервер. Однако не каждая система, чьи компоненты обмениваются данными посредством запросов-ответов, является REST (или же RESTful) системой. Чтобы система считалась RESTful, она должна “вписываться” в шесть REST ограничений:

1. Приведение архитектуры к модели клиент-сервер

В основе данного ограничения лежит разграничение потребностей. Необходимо отделять потребности клиентского интерфейса от потребностей сервера, хранящего данные. Данное ограничение повышает переносимость клиентского кода на другие платформы, а упрощение серверной части улучшает масштабируемость системы. Само разграничение на “клиент” и “сервер” позволяет им развиваться независимо друг от друга.

2. Отсутствие состояния

Архитектура REST требует соблюдения следующего условия. В период между запросами серверу не нужно хранить информацию о состоянии клиента и наоборот. Все запросы от клиента должны быть составлены так, чтобы сервер получил всю необходимую информацию для выполнения запроса. Таким образом и сервер, и клиент могут «понимать» любое принятое сообщение, не опираясь при этом на предыдущие сообщения.

3. Кэширование

Клиенты могут выполнять кэширование ответов сервера. У тех, в свою очередь, должно быть явное или неявное обозначение как кэшируемых или некэшируемых, чтобы клиенты в ответ на последующие запросы не получали устаревшие или неверные данные. Правильное использование кэширования помогает полностью или частично устранить некоторые клиент-серверные взаимодействия, ещё больше повышая производительность и расширяемость системы.

4. Единообразие интерфейса

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

5. Слои

Под слоями подразумевается иерархическая структура сетей. Иногда клиент может общаться напрямую с сервером, а иногда — просто с промежуточным узлом. Применение промежуточных серверов способно повысить масштабируемость за счёт балансировки нагрузки и распределённого кэширования. Приведем пример. Представим себе некоторое мобильное приложение, которое пользуется популярностью во всем мире. Его неотъемлемая часть — загрузка картинок. Так как пользователей — миллионы человек, один сервер не смог бы выдержать такой большой нагрузки. Разграничение системы на слои решит эту проблему. Клиент запросит картинку у промежуточного узла, промежуточный узел запросит картинку у сервера, который наименее загружен в данный момент, и вернет картинку клиенту. Если здесь на каждом уровне иерархии правильно применить кэширование, то можно добиться хорошей масштабируемости системы.

6. Код по требованию (необязательное ограничение)

Данное ограничение подразумевает, что клиент может расширять свою функциональность, за счет загрузки кода с сервера в виде апплетов или сценариев.

Преимущества, которые дает REST

У приложений, которые соблюдают все вышеперечисленные ограничения, есть такие преимущества: надёжность (не нужно сохранять информацию о состоянии клиента, которая может быть утеряна);

Коммуникация между клиентом и сервером

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

Чтобы все было (стало) понятно, будем разбирать клиент-серверную коммуникацию на примере некоторого RESTful приложения. Допустим, мы разрабатываем веб приложение, которое способно хранить информацию о клиентах и их заказах. Т.е. наша система способна манипулировать некоторыми сущностями: создавать их, редактировать, удалять, выдавать информацию о них. Этими сущностями будут:

В REST архитектуре клиенты отправляют на сервер запросы для получения или модификации данных, а сервера отправляют клиентам ответы на их запросы.

Запросы

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

Ниже мы рассмотрим более подробно каждую составляющую часть.

URI и Ресурсы

Данные, которые получают или изменяют клиенты посредством запросов, называют ресурсами. Основа клиент-серверного взаимодействия — манипуляция над ресурсами. Ресурсы в REST — это все, чему можно дать имя. Это в каком то смысле как классы в Java. В Java мы можем создать класс для чего угодно. Так и в REST — ресурсом может быть что угодно: пользователь, документ, отчет, заказ. Все это может быть как абстракцией некоторой сущности, так и чем-то конкретным, например, файлом — картинкой, видео, анимацией, PDF файлом. В рамках нашего примера у нас есть 3 ресурса:

Клиенты отправляют запросы на так называемые эндпоинты, или же конечные точки (end point). Если говорить очень просто, эндпоинт — это что-то вроде адреса в сети. Если углубляться в суть, можно сказать, что эндпоинт — это URI: последовательность символов, идентифицирующая абстрактный или физический ресурс. Uniform Resource Identifier — унифицированный идентификатор ресурса. Иногда конечную точку, или URI называют путем (path) — путем до ресурса. В рамках этой статьи мы будем использовать термин URI. У каждого конкретного ресурса должен быть уникальный URI. Ответственность за то, чтобы у каждого ресурса всегда был свой URI лежит на плечах разработчика сервера. В нашем примере разработчики это мы, поэтому будем делать это так, как умеем. Подобно тому, как в реляционной базе данных часто принято первичным ключом задавать некоторый числовой ID, в REST у каждого ресурса есть свой ID. Часто бывает так, что ID ресурса в REST совпадает с ID записи в базе данных, в которой хранится информация о данном ресурсе. URI в REST принято начинать с множественной формы существительного, описывающего некоторый ресурс. Например, со слова clients. Далее через слэш указывают ID — идентификатор некоторого конкретного клиента. Примеры:

Если мы продолжим эту цепочку и добавим еще и товары, получим:

С уровнями вложенности главное — делать URI интуитивно понятными.

HTTP метод

Метод HTTP (англ. HTTP Method) — последовательность из любых символов, кроме управляющих и разделителей, которая указывает на основную операцию над ресурсом. Существует несколько общепринятых методов HTTP. Перечислим те из них, которые наиболее часто используются в RESTful сервисах:

Заголовки

В запросах, как собственно и в ответах, присутствуют HTTP заголовки. В них отправляется дополнительная информация о запросе (либо ответе). Заголовки представляют собой пары ключ-значение. Список наиболее распространенных заголовков можешь почитать на странице в Википедии. Применительно к REST клиенты часто могут слать в запросе к серверу заголовок Accept. Он нужен, чтобы дать серверу понять, в каком формате клиент ожидает получить от него ответ. Различные варианты форматов представлены в так называемом списке MIME-типов. MIME (англ. Multipurpose Internet Mail Extensions — многоцелевые расширения интернет-почты) — спецификация для кодирования информации и форматирования сообщений таким образом, чтобы их можно было пересылать по интернету. Каждый MIME тип состоит из двух частей, разделяемых слэшем — из типа и подтипа. Примеры MIME-типов для разных видов файлов:

Итого, у запроса может присутствовать заголовок:

Данный заголовок говорит серверу, что клиент ожидает получить ответ в JSON формате.

Тело запроса

Пересылаемое клиентом сообщение на сервер. Есть у запроса тело или нет, зависит от типа HTTP запроса. Например, запросы GET и DELETE как правило не содержат никакого тела запроса. А вот PUT и POST могут содержать: тут все дело в функциональном назначении типа запроса. Ведь для получения данных и удаления по id (который передается в URL) не нужно слать на сервер дополнительные данные. А вот для создания нового ресурса (запрос POST) нужно этот ресурс передать. Также как и для модификации существующего ресурса. В REST для передачи тела запроса чаще всего используют форматы XML или JSON. Наиболее часто встречается JSON формат. Предположим, мы хотим отправить на сервер запрос, а в нем — создать новый ресурс. Если ты не забыл, в качестве примера мы рассматривали приложение, которое управляет заказами клиентов. Допустим, мы хотим создать нового клиента. В нашем случае мы храним следующую информацию о клиентах: Имя Email Номер телефона Тогда телом такого запроса может быть следующий JSON:

Собираем запросы воедино

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

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллерРуководство по REST архитектуре

Ответы

Скажем пару слов об ответах сервера. Ответ как правило состоит из следующих частей:

В целом заголовки ответов мало чем отличаются от заголовков запросов. К тому же, некоторые заголовки используются и в ответах, и в запросах. С телом ответа тоже, думаю, все понятно. В теле часто возвращается информация которую запросил клиент. Может возвращаться в том же формате JSON информация на GET запросы. А вот последняя часть, немного более интересна.

Коды HTTP ответов

Рассмотрим подробнее коды HTTP ответов. Приведем цитату из Википедии: Код состояния HTTP (англ. HTTP status code) — часть первой строки ответа сервера при запросах по протоколу HTTP. Он представляет собой целое число из трёх десятичных цифр. Первая цифра указывает на класс состояния. За кодом ответа обычно следует отделенная пробелом поясняющая фраза на английском языке, которая разъясняет человеку причину именно такого ответа. Примеры:

Клиент узнаёт по коду ответа о результатах его запроса и определяет, какие действия ему предпринимать дальше. Коды ответов подразделяются на несколько групп:

Создание RESTful сервиса на Spring Boot

Создание проекта

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Нажимаем кнопку Next. В следующем окне указываем тип проекта Maven, указываем Group и Artifact:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Нажимаем кнопку Next. В следующем окне нам необходимо выбрать нужные для проекта компоненты Spring Framework. Нам будет достаточно Spring Web:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Нажимаем кнопку Next. Далее осталось указать только наименование проекта и его расположение в файловой системе:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Нажимаем кнопку Finish. Проект создан, теперь мы можем увидеть его структуру:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Создание REST функционала

Аннотация @Service говорит спрингу, что данный класс является сервисом. Это специальный тип классов, в котором реализуется некоторая бизнес логика приложения. Впоследствии, благодаря этой аннотации Spring будет предоставлять нам экземпляр данного класса в местах, где это, нужно с помощью Dependency Injection. Теперь пришло время для создания контроллера. Специального класса, в котором мы реализуем логику обработки клиентских запросов на эндпоинты (URI). Чтобы было понятней, будем создавать данный класс по частям. Сначала создадим сам класс и внедрим в него зависимость от ClientService :

@RestController — говорит спрингу, что данный класс является REST контроллером. Т.е. в данном классе будет реализована логика обработки клиентских запросов

Далее мы пошагово будем реализовывать каждый метод контроллера, для обработки CRUD операций. Начнем с операции Create. Для этого напишем метод create :

Разберем данный метод:

@PostMapping(value = «/clients») — здесь мы обозначаем, что данный метод обрабатывает POST запросы на адрес /clients

Внутри тела метода мы вызываем метод create у ранее созданного сервиса и передаем ему принятого в параметрах контроллера клиента.

Далее реализуем операцию Read : Для начала реализуем операцию получения списка всех имеющихся клиентов:

Приступим к разбору:

В REST контроллерах спринга все POJO объекты, а также коллекции POJO объектов, которые возвращаются в качестве тел ответов, автоматически сериализуются в JSON, если явно не указано иное. Нас это вполне устраивает.

Внутри метода, с помощью нашего сервиса мы получаем список всех клиентов. Далее, в случае если список не null и не пуст, мы возвращаем c помощью класса ResponseEntity сам список клиентов и HTTP статус 200 OK. Иначе мы возвращаем просто HTTP статус 404 Not Found.

Далее реализуем возможность получать клиента по его id:

Данный метод будет принимать запросы на uri вида /clients/ , где вместо может быть любое численное значение. Данное значение, впоследствии, передается переменной int id — параметру метода.

Осталось реализовать две операции — Update и Delete. Приведем код этих методов:

Чего-то существенно нового в данных методах нет, поэтому подробное описание пропустим. Единственное, о чем стоит сказать: метод update обрабатывает PUT запросы (аннотация @PutMapping ), а метод delete обрабатывает DELETE запросы (аннотация DeleteMapping ).

Приведем полный код контроллера:

В итоге, структура нашего проекта выглядит следующим образом:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Запуск и тестирование

А для того, чтобы тестировать RESTful веб сервисы, нужно скачать новое ПО )

Дело в том, что GET запросы довольно просто отправлять из обычного браузера, а вот для POST, PUT и DELETE обычным браузером не обойтись.

Не переживай: чтобы отправлять любые HTTP запросы, можно воспользоваться программой Postman. Скачать её можно отсюда.

После скачивания и установки, приступаем к тестированию нашего приложения.

Для этого открываем программу и создаем новый запрос:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Нажимаем кнопку New в левом верхнем углу.

Далее выбираем Request:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Далее задаем ему имя и сохраняем его.

Попробуем теперь отправить POST запрос на сервер и создать первого клиента:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Создаем таким образом несколько клиентов. Затем меняем тип запроса на GET и отправляем его на сервер:

Что такое rest контроллер. Смотреть фото Что такое rest контроллер. Смотреть картинку Что такое rest контроллер. Картинка про Что такое rest контроллер. Фото Что такое rest контроллер

Общие итоги

Поздравляю: мы рассмотрели довольно тему REST. Весь материал получился объемным, но, надеемся, полезным для тебя:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *