что такое рест контроллер
Основы REST: теория и практика
Авторизуйтесь
Основы REST: теория и практика
REST, Representational State Transfer, является архитектурным стилем для обеспечения стандартов между компьютерными системами в сети, что облегчает для систем обмен данными друг с другом. Системы, отвечающие требованиям REST и часто называемые RESTful, характеризуются тем, что не имеют сохранения состояния и разделяют интересы клиента и сервера. Мы рассмотрим, что означают эти термины и почему они являются полезными для услуг в Интернете.
Разделение клиента и сервера
В архитектурном стиле REST реализация клиента и реализация сервера могут быть выполнены независимо друг от друга. Это означает, что код на стороне клиента может быть изменён в любое время без ущерба для работы сервера, а код на стороне сервера может быть изменён без влияния на работу клиента.
До тех пор, пока каждая сторона знает, какой формат сообщений следует направлять другой стороне, они могут храниться модульно и раздельно. Отделяя задачи пользовательского интерфейса от задач хранения данных, мы повышаем гибкость интерфейса между платформами и улучшаем расширяемость за счёт упрощения компонентов сервера. Кроме того, разделение позволяет каждому компоненту развиваться независимо.
Используя интерфейс REST, различные клиенты попадают в одни и те же конечные точки REST, выполняют те же действия и получают одинаковые ответы.
Отсутствие сохранения состояния
Системы, которые следуют парадигме REST, не имеют сохранения состояния, что означает, что серверу не нужно знать о состоянии клиента и наоборот. Таким образом, и сервер, и клиент могут понять любое полученное сообщение, даже не увидев предыдущих сообщений. Это отсутствие сохранения состояния обеспечивается за счёт использования ресурсов, а не команд. Они описывают любые объекты, документы или вещи, которые могут потребоваться для хранения или отправки в другие службы.
25–27 ноября, Онлайн, Беcплатно
Эти ограничения помогают RESTful-приложениям достигать надёжности, быстрой производительности и расширяемости, как компонентам, которые могут быть управляемы, обновлены и повторно использованы, не затрагивая систему в целом даже во время её работы.
Теперь мы изучим, как на самом деле происходит взаимодействие между клиентом и сервером, когда мы внедряем RESTful-интерфейс.
Взаимодействие между клиентом и сервером
В архитектуре REST клиенты отправляют запросы на поиск или изменение ресурсов, а серверы отправляют ответы на эти запросы. Давайте рассмотрим стандартные способы направления запросов и ответов.
Отправка запросов
REST требует, чтобы клиент сделал запрос на сервер для получения или изменения данных на сервере. Запрос обычно состоит из:
Существует 4 основных метода НТТР, которые мы используем в запросах для взаимодействия с ресурсами в системе REST:
В заголовке запроса клиент отправляет тип контента, который он может получить с сервера. Это поле называется Accept. Оно обеспечивает, что сервер не посылает данные, которые не могут быть поняты или обработаны клиентом. Параметры типов контента — это типы MIME (или Multipurpose Internet Mail Extensions, о которых вы можете прочитать больше в MDN Web Docs).
Типы MIME, используемые для указания типов контента в поле Accept, состоят из типа и подтипа. Они разделены слэшем (/).
Другие типы и часто используемые подтипы:
Например, клиент, имеющий доступ к ресурсу с идентификатором 123 в ресурсе статей на сервере, может отправить запрос GET следующим образом:
Запросы должны содержать путь к ресурсу, на котором должна выполняться операция. В RESTful API пути должны быть разработаны так, чтобы помочь клиенту понять, что происходит. Обычно первая часть пути должна быть множественной формой ресурса. Это позволяет легко читать и понимать вложенные пути.
Пути должны содержать информацию, необходимую для определения местоположения ресурса с необходимой степенью конкретности. При ссылке на список или коллекцию ресурсов не всегда необходимо добавлять идентификатор. Например, запрос POST на путь somesite.com/persons не будет нуждаться в дополнительном идентификаторе, так как сервер генерирует идентификатор для нового объекта.
В тех случаях, когда сервер отправляет клиенту полезную нагрузку, он должен включать тип контента в заголовок ответа. Это поле заголовка контента предупреждает клиента о типе данных, которые он посылает в теле ответа. Эти типы контента являются типами MIME, точно так же, как они находятся в поле Accept заголовка запроса. Тип контента, который сервер возвращает обратно в ответе, должен быть одним из параметров, указанных клиентом в поле принятия запроса.
Например, клиент получает доступ к ресурсу с идентификатором 123 в разделе статей с этим запросом GET:
Сервер должен отправить обратно контент с заголовком ответа:
Это означает, что запрашиваемый контент возвращается в тело ответа с text/html — типом контента, который клиент будет в состоянии принять.
Коды ответов
Ответы от сервера содержат коды состояния для оповещения клиента об успехе операции. Как разработчику вам не нужно знать каждый код состояния (их много), но вы должны знать самые распространённые и то, как они используются.
Для каждого метода НТТР ожидаются коды статуса, которые сервер должен вернуть в случае успеха:
Если операция не работает, вернётся наиболее конкретный код состояния, соответствующий возникшей проблеме.
Предположим, у нас есть приложение, которое позволяет вам просматривать, создавать, редактировать и удалять клиентов и заказы для небольшого магазина одежды, размещённого на сайте fashionboutique.com. Мы можем создать НТТР API, который позволит клиенту выполнять следующие функции.
Если бы мы хотели увидеть всех клиентов, запрос выглядел бы так:
Возможный заголовок ответа будет выглядеть следующим образом:
Создание нового клиента путем размещения данных:
Затем сервер генерирует идентификатор этого объекта и возвращает его клиенту с таким заголовком:
Для просмотра одного клиента мы используем метод GET, указывая идентификатор этого клиента:
Возможный заголовок ответа будет выглядеть следующим образом:
Мы можем обновить этого клиента, вставив новые данные с помощью метода PUT:
Мы также можем УДАЛИТЬ этого клиента, указав его идентификатор:
Практика с REST
Давайте представим, что мы создаём сайт для сбора фотографий. Мы хотим сделать API, чтобы отслеживать пользователей, места проведения и фотографии этих мест. Этот сайт имеет index.html и style.css. Каждый пользователь имеет имя пользователя и пароль. Каждая фотография имеет место проведения и владельца (т.е. пользователя, который сделал фотографию). Каждое место имеет название и адрес. Можете ли вы разработать систему REST, которая будет учитывать:
Для начала опишите:
Открытый урок «Создание REST-клиентов на Spring»
И снова доброго времени суток! Совсем скоро у нас стартует обучение очередной группы «Разработчик на Spring Framework», в связи с чем мы провели открытый урок, что стало уже традицией в преддверии запуска. На этом вебинаре говорили о разработке REST-клиентов с помощью Spring, а также детально узнали о таких технологиях, как Spring Cache, Spring Retry и Hystrix.
Преподаватель: Юрий Дворжецкий — тренер в Luxoft Training Center, ведущий разработчик, кандидат физико-математических наук.
Вебинар посетила совершенно разная аудитория, оценившая свои знания по Spring в пределах 0-6 баллов по 10-бальной шкале, однако, судя по отзывам, открытый урок показался полезным даже опытным пользователям.
Пару слов о Spring 5
Как известно, Spring Framework является универсальным и довольно популярным фреймворком для Java-платформы. Spring состоит из массы подпроектов или модулей, что позволяет решать множество задач. По сути, это большая коллекция «фреймворков во фреймворке», вот, например, лишь некоторые из них:
Чтобы показать некоторые особенности работы Spring, прекрасно подходит тема блокировки сайтов, так как это сейчас модно)). Если хотите активно поучаствовать в уроке и попрактиковаться, рекомендуется скачать репозиторий с кодом сервера, который предложил преподаватель. Используем следующую команду:
git clone git@github.com:ydvorzhetskiy/sb-server.git
Далее просто запускаем, например, так:
Самым большим достижением Spring Boot является возможность запустить сервер простым запуском Main-класса в IntelliJ IDEA.
В файле BlockedSite.java находится наш исходный код:
А вот содержимое контроллера BlockedSitesController.java:
Также обратите внимание на вложенную БД в pom.xml:
Теперь простым и незатейливым образом сохраняем в нашу БД через репозиторий два заблокированных сайта (DemoServerApplication.java):
Что же, пришла пора писать клиента к этому серверу. Но прежде чем к этому перейти, нужно кое-что вспомнить.
Давайте перечислим некоторые HTTP-методы (глаголы):
А теперь, давайте подумаем, какие из вышеперечисленных HTTP-методов идемпотентны? Конечно, подразумевается, что вы соблюдаете семантику. Если не знаете, то подробнее об этом рассказывает преподаватель, начиная с 26-й минуты видео.
Для того чтобы писать REST-контроллер, нужно вспомнить, что такое REST:
Во-вторых, самое важное ограничение в REST — отсутствие состояния клиента на сервере. Предполагается, что серверу клиент всегда передаёт всё необходимое состояние с каждым запросом, то есть состояние сохраняется на стороне клиента, и нет никаких сессий на сервере.
Как писать клиента на Spring
Для продолжения работы рассмотрим и запустим клиента (используем ссылку на репозиторий):
Это уже написанный клиент и консольное приложение, а не веб-сервер.
У клиента есть конфигурация:
А вот содержимое файла SiteServiceRest.java:
И, как обычно, ждём ваших комментариев к прошедшему открытому уроку!
Приветствую.
Летом вышел релиз новой версии фреймворка, но поработать с ним получилось только недавно. В новой версии было добавлено много полезных штук, об одной из них, а именно ApiController, я хотел бы сегодня рассказать.
Благодаря им стало возможно делать RESTFull Api без лишних усилий. На небольшом примере заодно разберем работу с OData.
Создадим новый ASP MVC 4 Empty Project. Для примера, создадим контроллер, который будет реализовывать функционал по работе с топиками. Для начала добавим простую модель:
Добавим новый контроллер, унаследуем его от ApiController, пока без никаких действий:
Теперь наш контроллер доступен по адресу: localhost/api/topic. Если мы перейдем по нему, то получим сообщение о том, что в нашем контроллере не найдено ни одного действия, реализующего ответ на GET запрос. Так добавим же его в наш контроллер:
Если мы сделаем запрос на localhost/api/topic, то получим следующий ответ:
Почему ответ в формате XML? Потому, что если мы не указали Content-Type в запросе, сериализатор по умолчанию вернет нам XML. Давайте получим в формате JSON. Для этого можно воспользоваться удобным приложением для Chromium — REST Console (за подсказку подобных плагинов/расширений для других браузеров буду благодарен). Укажем в Content-Type «json» и получим:
Коллекцию топиков мы получили. Добавим новое действие в контроллер для получение одного топика по его идентификатору:
Запрос по адресу localhost/api/topic/5 вернет нам следующий ответ:
Добавим действие для добавления нашего топика:
И отправим по адресу localhost/api/topic следующий запрос:
Также в запросе укажем необходимые параметры: Request Method — PUT и Content type — application/json (Не перепутайте этот Content type с тем, о котором я говорил выше. Этот указывается в Content Headers, чтобы байндер знал, в каком формате пришли к нему данные, а для запроса топиков мы указывали Content type в Accept для сериализатора). И получим в ответ:
Кстати о возвращаемом значении. В нашем случае я вернул строку с сообщением. Также можно возвращать HttpResponseMessage и манипулировать кодами ответа, в зависимости от успеха/неудачи операции:
Действие для метода POST описывать не буду, т.к. отличий от PUT — нет. Добавим последнее действие DELETE:
Роутинг
А что, если мы захотим использовать наш контроллер для предоставления простого апи, без поддержки методов?
Добавим новый контроллер с двумя действиями:
Если мы отправим запрос на localhost/api/testroute/5, то получим ошибку: Multiple actions were found that match the request. Связано это с тем, что Selector не знает какое действие ему выбрать. Давайте откроем WebApiConfig.cs и посмотрим на заданный там маршрут:
Как видим, у нас не задано в шаблоне определение действия для контроллера. Необходимое действие контроллера выбирается на основе Method’a запроса. Добавим ниже еще один маршрут:
После этого, если сделать запрос к нашему контроллеру с прямым указанием необходимого действия (localhost/api/testroute/gettopic/5), то мы получим ответ. Либо можно задать у самого действия необходимый маршрут для него с помощью атрибута ActionName:
Spring REST с примером
Сегодня поговорим о такой теме как REST API. Попробуем понять что же это такое и напишем свой REST с помощью Spring Boot.
Данная статья является прямым продолжением Spring Boot — пример с Postgres и JPA. Поэтому объяснять что такое Spring Boot я уже не буду. Проект, к которому я буду подключать REST, я также взял из статьи указаной выше.
Для начала, предлагаю разбить статью на план:
Rest (representational state transfer) — это программный архитектурный стиль для создания веб сервисов. Веб сервисы, которые соответствуют Rest стилю называют RESTful.
Данные системы предназначены для передачи и манипулирования данными по сети с помощью предварительного написанного набора операций.
ФУХ… Написанное выше — это перевод из Википедии;) Такое нелегко запомнить, а тем более понять. Если рассказывать о данном стиле более просто то: Rest это очень удобная и простая штука для передачи данных. Я намерено упускал из объяснения слово «протокол». Потому что REST это НЕ ПРОТОКОЛ. И это одно из его главных отличий от SOAP.
Вот мы и подошли к разнице между REST и SOAP.
Почему я так хочу затронуть этот момент в данной статье? Данный вопрос очень часто задают на собеседованиях. В том числе и я;) И, к сожалению, многие кандидаты не могут ответить достаточно быстро и просто на такой, казалось бы, банальный вопрос.
Вот Вам пару отличий данных подходов:
Если Вы скажете хотя бы первое отличие — это уже будет 90% ответа. Именно то, что REST не протокол, зачастую забывают или не знают большинство кандидатов.
Теперь, перейдем на практичный пример реализации REST API с помощью Spring Boot.
Сейчас Вы увидите — насколько просто и быстро сделать данное API на Spring Boot. Фреймворк делает всю черновую работу за программиста и оставляет возможность просто сосредоточить усилия на бизнес-проблеме.
Для начала нам нужен простой проект Spring Boot. Я выкачал его из репозитория из предыдущей статьи. По желанию, можно создать проект с нуля. Как это делать можете также почитать из других моих статей по Spring. Например, в моей недавней статье Spring scheduler — выполнение кода по расписанию.
Главное, что нужно добавить для возможности реализации REST это зависимости для веб.
Все! Наш проект готов к написанию REST API. Мой проект выглядит так:
Если Вы все делали по инструкции — то проект должен быть примерно похож. За исключением класса UsersController. Его у Вас пока нет. Давайте его напишем.
Для начала создадим пакет controller. В него поместим класс UsersController.
Для того, чтобы данный класс стал рест контроллером достаточно навесить на него аннотацию @RestController. Spring теперь будет обслуживать данный класс как REST API.
А дальше все по сценарию контроллеров которые мы уже видели в статье Spring MVC первое веб приложение. Только вместо того, чтобы возвращать страницы, мы будем возвращать JSON объекты.
Как я уже упоминал ранее, REST позволяет работать с любым типом данных и Spring Boot нас в этом никак не ограничивает. Просто, по умолчанию, если ничего не указать в методе — то будет возвращать JSON. Spring использует библиотеку Jackson для того чтобы конвертировать объекты Java в JSON и наоборот. Подключать ее дополнительно не нужно.
Для того, чтобы возвращать xml необходимо добавить библиотеку jackson-dataformat-xml. Вот ее полный код:
Теперь, посмотрим на сам код контроллера:
Попытаюсь просто объяснить что происходит в данном примере.
В главном классе Spring Boot я добавил небольшой метод для заполнения базы данных после запуска приложения. Для тех, кому лень скачать проект с гитхаба, дублирую этот класс здесь:
После запуска приложения наша база данных заполниться этими полями. Теперь, можно взять Postman или просто попробовать вызвать наши методы через браузер.
вызов рест ендпоинта в браузере
В постман результат будет иметь более привлекательный вид:
И чтобы создать нового пользователя нужно вызвать метод POST с телом нового пользователя:
Результатом будет создание нового пользователя в базе данных.
Как видите, код очень простой и требует минимальных настроек со стороны программиста. Новые фреймворки и инструменты позволяют сосредоточить усилия на проблеме, вместо настроек проекта и кода. Что, конечно же, не может не радовать.
Это все, что касается REST на Spring Boot. Дальнейшие нюансы Вы уже увидите когда сами начнете эксперементировать с кодом.
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 и протестировать его в боевых условиях с помощью тестового приложения.
Шаг 1. Создание проекта и подключение зависимостей
Создаем Maven проект называем его SpringRESTExam:
Теперь давайте подключим зависимости, так как мы будем реализовывать REST с помощью Spring Framework, то нам потребуются следующие зависимости:
Мы подключили две зависимости, первая это Spring MVC, вторая это поддержка Servlet API.
Еще для удобства я использую следующие два плагина:
Первый плагимы говорит о том, что проект будет компилироваться Java 7, а второй конфигурирует сборку war архива и говорит, что мы не требуемся в использовании web.xml файла.
Шаг 2. Создание сущности
Для того чтобы продемонстрировать REST в котором мы будем манипулировать данными мы создадим объект MyDataObject в который добавим все необходимые для наших целей поля.
Я предпочел хранить в этом объекте время и сообщение.
И так что же нам надо сделать?
Мы создадим веб-страницу на которой будет 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.
Выглядеть эта страничка будет следующим образом:
Шаг 6. Деплоим и тестируем
Теперь запускам Tomcat либо в моём случае Glassfish4 и деплоим:
На этом все 🙂 Возникнут вопросы, задавайте их в коментариях.