Делаем простое REST приложение с нуля. Spring Boot REST
HTML-код
- Опубликовано: 16 июн 2018
- Spring Boot Rest Application: Создаём простое Spring Boot Rest приложение. Spring - мощный фреймворк из мира Java. Т.к. Java достаточно сложный для новичков язык, лучше продвигаться методом изучения простых примеров.
Поддержать проект:
➡ Стать спонсором ruclips.net/user/letscodedrujoin
➡ Patreon / letscodedru
➡ Яндекс.Деньги money.yandex.ru/to/4100145167...
➡ PayPal paypal.me/letscodedru
➡ Qiwi qiwi.me/letscode
Ссылка на git репозиторий из видео:
github.com/drucoder/sarafan/t...
Спецификации на rest как таковой не определено, так что понятие это сборное и представляет из себя сбор общепринятых практик. Как следствие - вокруг этого понятия постоянно возникают споры о том как это должно выглядеть и работать.
Для упрощения нашей задачи мы возьмём только несколько основных правил:
1. Все данные, фигурирующие в обмене будут передаваться в формате json
2. Адресация данных осуществляется через url приложения
3. Вид операции работы с данными на сервере определяется типом http запроса: GET для получения данных, POST для создания нового объекта, PUT для обновления существующего объекта и DELETE для удаления.
Для упрощения создания заготовки нашего spring boot приложения будем использовать spring initializr:
start.spring.io/
Для начала нам достаточно только двух пакетов: spring mvc для создания контроллера и spring devtools для оперативной перезагрузки ресурсов.
Создаём новый контроллер MessageController, аннотированный как @RestController, содержащий методы для обработки всех перечисленных выше видов запросов: на чтение списка сообщений, получение одного сообщения, создание и модификация существующего и удаление.
Для тестирования созданных методов мы будем делать запросы к серверу через консоль браузера. Для этих целей нам понадобится современный браузер с хорошим инструментарием для разработчика. Из двух наиболее подходящих браузеров (FireFox и Chrome) я использую Chrome и все примеры показываю в нём.
Современные браузеры поддерживают метод fetch языка javaScript, позволяющий делать асинхронные http запросы.
Для каждого из тестируемых запросов я написал заготовки, которые вы можете найти тут:
gist.github.com/drucoder/a1d8...
Подробнее о методе fetch можно почитать тут:
learn.javascript.ru/fetch
Метод fetch использует Promise для обработки результатов запроса. О Promise можно почитать тут:
learn.javascript.ru/promise
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
➡ Твиттер: / letscodedru
➡ Чат в Discord: / discord
➡ Группа Вконтакте: letscodedru
➡ Канал в Telegram: t.me/letsCode_dru
➡ Чат в Telegram: t.me/joinchat/FeiP9xEhqHajfqh...
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
➡ Ссылка на канал: / @letscodedru
➡ Ссылка на Яндекс.Дзен: zen.yandex.ru/media/id/5ac209... - Наука
fetch('/message', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({text: 'message 4'})}).then(result => console.log(result))
Как я долго ждал начала этой темы, блин всё крутецки-круто, я доволен)))
Очень профессиональное изложение. Спасибо за ваш труд!
Благодаря "свитеру" смог сам начать что-то пилить на Spring Boot. Теперь следующая таска - постигнуть REST. Чувствую неизбежное просветление. Спасибо автору!
Отдельное спасибо за сценарии тестирования!
Как всегда великолепно. Спасибо!!!
Не устаю благодарить за такие актуальные видосики!
Андрей, ты без облизывания один из лучших встреченых преподавателей, не бросай ведение уроков. Давно зрела мысль о том что xml сейчас относится скорее к легаси, никто так не позиционировал эту технологию, а сам такой вывод сделать было боязно и вот ты первый её поддержал).
В будущем так же хотелось бы увидеть про логгирование.
Не заблуждайтесь. Xml как транспорт SOAP протокола используется во всех более менее крупных проектах, посмотрите хотя бы на чем сделаны гос услуги...
А если с облизыванием?)
Это лучшее, что можно найти на эту тему новичку
это наверное лучший урок из всех которые я нашел . Автор красавчик!!!
много чему учусь на этом канале. поистине качественный образовательный канал
чисто спасаешь, уже разочаровался что ничего годного не найду, но это топ, спасибо большое!)
Идеально! Коротко и по делу. Респект!
Отличное видео! перехожу с php Laravel на Java Spring и тут на - такой подарочек - целый цикл уроков по тематике, которая мне так важна. Я тоже бывший 1с-ник с Мисты!
Тоже подумываю так сделать, но чет посмотрел - отталкивает сложность самой джавы в сравнении с php
Спасибо! Отличный и лаконичный материал!
Очень полезно!Спасибо Вам большое)
Норм, лучше заходит, чем более старые уроки по спрингу.
Божественно.
Спасибо огромное за видео!
Самый отличный и понятный ролик на ютубе
Благодарю! Очень полезно!
Ты что бог? Единственный кто мне реально помог понять как это работает.
что хочешь делай, но не останавливайся пилить такие видосики
Thank you so much for your work!))))
Реально КРУТЫЕ уроки!!!!!!!!!!!!!!!!!
Голосую за:
4. Docker
6. Тестирование с JUnit
ну ок, докер уже пару раз спрашивали, попробуем деплоить это приложение в виде докер контейнера
а с тестами уже много раз писал: будут тесты, что ж вы ддосите одинаковыми вопросами?))
@@letsCodeDru Чет тестирования JUnit & Mockito так и не дождались....
@@fredyord3544 ruclips.net/video/QrSR1fm9JwA/видео.html
Android приложение с Back End на Spring
@@letsCodeDru может многие TDD ждут, а не на потом тесты откладывать?
после чистой java и сервлетов, spring это эйфорическая радость))
Вы прекрасны, спасибо вам
Ожидаем, пока Идея выкачает весь интернет, а-а-а-ааааа)))))
Спасибо!!!!
Только хотел предложить сделать такое видео))
Афтар вашпе молодэс :)
Отличное видео. Все по делу, четко, доступно и понятно. Стопицот плюсов.
Спасибо большое!
Видос зачет!
Савсибо!!!!!!
Было бы супер курс
Прошлая серия выпусков придала +100 к настроению, мотивации, знаниям. Надеюсь, что эта будет такая же)
Есть много предложений:
1. Со строками понятно, а как быть, если нужно работать с датой, zip архивами, картинками?
2. Добавить возможность работать не только с JSON но и с XML
3. Было бы интересно прикрутить не sql-ную бд типа Mongo
4. Docker
5. Документирование с помощью Swagger
6. Тестирование с JUnit
7. Прикрутить security
Не могли бы вы ответить, что из вышепредложенного можно ожидать в дальнейших видео?
Самому разобраться не проблема, но всегда гораздо лучше, когда объясняет профи с опытом, как ПРАВИЛЬНО все сделать. Огромное спасибо заранее
1. Даты перегоняются в строки при интеропе - это правило. Файлы через контроллеры пропускаются одинаково, а обработка этих файлов - уже вне юрисдикции спринга. Но с файлами и датами будем работать.
2. ну на кой вам xml?? господа, забудьте о нём! приведите 2 не притянутых за уши и не-легаси сценария, когда он реально нужен - тогда сделаю по нему материал
3. Монго - это другая история, по ней прорабатываю следующую серию видосов :)
4. Докер не связан со спрингом никак. Рассматривать его планировал, но в отдалённом будущем, ибо это не про яву, а про devops больше
5. тема хорошая, но её потом отдельно одним видео можно будет сделать с примером на текущем приложении. Т.к. если я еще в каждом видео буду по паре минут на доки тратить - мы очень скоро придём к полуторочасовым видео
6-7. будет
@@letsCodeDru 2. Кровавый энтерпрайз же! Например, SAPовская ESB (шина данных) умеет работать либо через SOAP с XML(web-service), либо через REST с JSON/XML.
Т.к. между серверами приложений используется SOAP (ибо описание веб-сервиса делается один раз на сервере, а клиенты просто подтягивают себе wsdl-файл и получают готовую структуру), то один фиг придётся с ним работать.
@@internet_newbie4286 Поэтому самый лёгкий способ это запиратить IDEA
СПАСИБО!!!
Крутяк мне как раз надо запилить rest приложение, только на фронте у меня angular :)
Ангуляр 2+ хорош, но мне архитектура и ценности проекта не очень заходят. Но когда-нибудь и до него, боюсь, доберёмся))
В следующем видео хотелось бы увидеть не только front, но и работу с бд)
Всему своё время. Будет и БД, и Security, и еще чего-нибудь интересного)
спасибо за видео. отдельно Spring Boot понятно, отдельно Vue вроде тоже понятно, REST пока непонятно и чтобы с нуля элементарно запилить хоть что-то нужно рыться, читать всякий бред программистов 80-го уровня на форумах и среди абзацов текста находить те самые элементарные вещи, которые искал. а тут все в одном видео, без лишней шелухи.
Здравствуйте! Спасибо большое Вам за видеоуроки!! подскажите, с какого по какое видео описывается фронт? очень срочноо. Буду очень признателен
видео супер!)
Не могли бы вы снять видео как правильно разрабатывать модульный проект?)
Если придумаю достойный пример. Очень не хочется натянутый пример делать)
Я не очень понял, что за инициализация была в двойными скобками, поэтому решил погуглить. Я правильно понимаю, что это просто синтаксический сахар и так делать не следует, судя по тому, что я прочитал (2й ответ) stackoverflow.com/questions/1958636/what-is-double-brace-initialization-in-java
Спасибо.
Блестящее начало.
fetch полезен, если кому-то недоступны REST клиенты?
Спасибо большое, курс отличный. На 10:15 возможно лучше будет отправить в getMessage(id), который получаем через @PathVariable - так как на фронте часто бывало так, что при редактирование забывали запихнуть в объект id - и бек кидал 404. Ну это по-моему личному опыту если что)) автору респект
Спасибо. Полезное видео. Как раз что-то такое искал. Я, правда, не понял, зачем такая сложная структура хранения: List, в нём Map, в ней ключ "id" и ключ "text". Одно сообщение - это одна мапа с двумя строками. Может лучше просто без всяких списков взять мапу, где ключ строка (id) и сообщение - значение?
Нормально вгрузил
В Idea в меню "Tools" есть утилита "Testing RESTful Web Services"
Теперь даже просто можно создавать .http файлы и выполнять их как запросы
Советую для тестирования rest api использовать postman. Очень удобное приложение.
Я добавляю новые поля (например name) в сущность Сообщения, но при помощи fetch запроса из вашего gist не удается добавить объекту их значения
В последних версиях IDEA можно создать новый проект используя Spring boot initialzr прямо из IDEA, и выбрать необходимые опции, версию Java, сборщик, дополнительные инструменты. (Это чтобы не скачивать стартовый проект архивом)
File - New - Project - Spring Initialzr
Такая возможность есть в ultimate версии. Уточнение, чтобы люди в community версии не искали
@@hex_r В VS Code тоже есть плагин для этого.
Спасибо за рест! Как раз скоро с ангуляром придется работать.
Жаль не освятил oauth2. А то рест без авторизации - как :)
-------
И еще пора открывать рубрику "за кадром", где у тебя не компилится и ты неистово метеришься. ))
А то прям все так гладко как по маслу идет, аж расстраиваюсь от своей рукожопости, когда переписываешь с экрана и не работает с 1 раза.
OAuth2 будет скоро
Стадию "неистово материться" я давно прошёл и когда что-то падает на ошибку, я радуюсь. Ошибка - это хорошо, это понятно что делать. Плохо, когда ошибки нет, а работает через задницу :(
Советую всем вместо консоли скачать приложение Postman, очень удобно, разобрался быстро как пользоваться.
Там не нужно писать эти методы, если не задрот)
Можете, пожалуйста, подсказать, в каком видосе объясняется тестирование?
9:05 - вопрос - что будет со значением счетчика при почти одновременных запросах от нескольких пользователей POST-метода - race condition?
Объект контроллера создается только один раз создается за время жизни сервиса? Или при каждом запросе новый объект?
Очень хотелось бы увидеть видео про Spring for Android. Заранее спасибо))
В момент проблемы с редактором я пошел учить основы)
Подскажите пожалуйста как в строке 52 "messageFromDB.putAll(message)" мы ложим message и он переписывается в коллекции messages? Ведь мы явно не переписываем его, а только работаем с объектом messageFromDB и обратно его не ложим.
Привет
Сделал всё как в видео и всё ок, работает, но когда подключаю js или css локальные, то в консоли пишет 404. Как можно в данном случае подключить скрипты и стили?
Если добавляешь просто в static - тогда возвращает, но есть в директорию добавляешь, допустим, в js.
Что, у меня у одного были ошибки из-за отсутствия добавленных полей у сущности (link, linkTitle, linkDescription, linkCover)?
В файле миграции добавил новые поля - все ок
Подскажите как выключить CORS. Я вместо Vue пишу на React на другом порте.
Рассказываю как можно еще тестировать rest через Idea, а не через консоль браузера. Создаете File->Http Request. В него помещаете такое содержимое
### Get request with a header
GET localhost:8080/message
Accept: application/json
### Send POST request with json body
POST localhost:8080/message
Content-Type: application/json
{
"text": "Fourth message"
} . Слева появляются стрелочки, как при запуске проекта. Таким образом можно проводить тесты.
Спачибо за видео! Заметил ошибку, в методе update(PutMapping) вы не сохраняете изменения в "базу данных"
Привет. Что делать если при попытке открыть проект я получаю сообщение - Support for clients using a tooling API version older than 3.0 was removed in Gradle 5.0. You are currently using tooling API version 2.13. You should upgrade your tooling API client to version 3.0 or later. Грейдл новый скачал, установил, в идее папку прописал.
почему-то когда вывожу список, названия параметров и их значения обрамлены обратным слэшем: ["{\"name\":\"имя\",\"description\":\"описание\", и т.д.
если вывожу один элемент - все норм.
это норм или как-то лечится?
go go go go
После компиляция контроллер не работает 404 error
Здравствуйте. Если меседж кириллица и выводятся кракозяблы что сделать, куда смотреть?
у меня fetch в Chromium работает, а в Firefox нет
Если у кого-то не работают аннотации:
@DeleteMapping({"id"})
@PutMapping({"id"})
То можно заменить их на такие:
@RequestMapping(value="{id}", method=RequestMethod.DELETE)
@RequestMapping(value="{id}", method=RequestMethod.PUT)
Счётчик потокобезопасен?
ты не хотел бы переписать курс под новую версию спринг бута и под новую версию джавы и вью?
Подскажите, пожалуйста, мне требуется написать микросервис, который через REST будет принимать данные и совершать некоторые действия, к примеру, отправку почты. Это вот так и делается, или микросервисы пишут по другим тенологиям?
p.s. у Вас замечательные курсы, пожалуй, лучшее, что я видел в интернете, а видел не так и мало. Спасибо!
Reactive Microservices Architecture Jonas Boner. Описаны принципы разработки микросервисов. Проектирование микросервисов основано на асинхронности, реализация которой наилучшим способом справляется Node.js. На java по-моему это тоже реализуемо
Так в IntelliJ есть встроенный механизм создания проекта через Spring Initializr, т.е. без непосредственной необходимости сайта start.spring.io и, соответственно, скачивания и распаковки сгенерированного этим сайтом пакета...
Все верно. Но про сайт тоже знать надо
letsCode
Я просто тащусь от IDEA!.. 😀
Кто может подсказать, почему при попытке найти несуществующий элемент в браузер получаю не только 404 но и простыню в виде stackTrace?
Сделал вроде как 1 в 1
Не знаю почему у автора не появляется стектрейс, но даже в документации по SpringBoot "Exception Handling in Spring MVC" есть статья по этому поводу. spring.io/blog/2013/11/01/exception-handling-in-spring-mvc . Решается она путем сокрытия информации от пользователя либо тупо комментирования блока стектрейс. Но почему у автора такого нет - я не понимаю. Объясните плз
Потому что ты удалил элемент по адресу "/message/4" и заходишь в браузере по "/message/4". Тем самым выполняется GET запрос по "/message/4" и пробрасывается ошибка, которую ты никак не обработал. Т.о. текст ошибки отправляется из сервера в браузер. Видеть стектрейс сервера в браузере грубейшая ошибка. Я думаю в будущих уроках этот вопрос решается. А вообще почитай www.restapitutorial.ru/lessons/httpmethods.html . Тут описано, как все должно быть в продакшене при запросах к серверу
А как с помощью Maven делать VUE?
Почему мы лихо навешиваем findFirst на результат фильтрации в 'getOne()'?
К тому же мы, кажется, исключили возможность занесения дублирующих записей {id:value) путем инкрементирования счетчика
Может быть, можно не включать findFirst?
Не могли бы вы также пояснить, почему потребовалось заменить @Controller на @RestController?
Потому что метод filter возвращает коллекцию и в ней не факт, что что-то будет, а findFirst вернёт Optional, который поможет обработать такой кейс, либо нормально вернёт корректное значение
@Controller ожидает, что на выходе из метода будет либо имя шаблона для рендера, либо строка перенаправления на другой URL, а @RestController возвращает голые данные из ответа (предварительно сериализовав их). Можно было бы и в контроллере так делать, но для каждого метода пришлось бы писать доп. аннотацию @ResponceBody
Поясните, пожалуйста:
"fetch .... система подсказывает готовый скрипт, который я использовал..."
Что именно (и откуда) 'система' подставляет в список вариантов при обращении к fetch в консоли?
к сожалению, это просто записи из истории :( был бы счастлив, если бы консоль браузера умела так))
а в целом этот список формируется из предыдущих запросов пользователя. Т.е. если вы один раз введёте в консоли какую-то команду, браузер будет предлагать её потом постоянно, когда будет видеть похожий текст
Спасибо за толковое видео! Но хотелось бы чтобы во время написания кода давались пояснения импользуемых аннтоаций. Чем @requestParam отличается например от @RequestBody и @PathVariable. На английском я конечно где-то могу прочитать абстрактное пояснение, но всегда понятний когда на конкретном, разрабатываемом примере. А так все замечательно.
docs.spring.io/spring/docs/5.1.4.RELEASE/javadoc-api/org/springframework/web/bind/annotation/package-summary.html Я считаю, что такой формат идеально подходит. Если что-то хочется изучить детальней, то просто идешь читать в документацию.
Посмотрите на х2 на часы сверху
Такая ошибка, мб кто встречал - после распаковки пакета, при постройке проекта (загрузке внешних зависимостей на моменте Build model'....plugins.gradle.model.ExternalProject') в идее выбивает ошибку
java.lang.AbstractMethodError: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierImpl.getModuleIdentifier()Lorg/gradle/api/artifacts/ModuleIdentifier;
Cause: invalid type code: CD
у меня было подобное, в конфиге стояла версия джавы, которая не соотвествовала версии установленную при генерации проекта на страт.спринг.ио
ТЫДЫЩ!
Спасибо за видео. Не давно закончил читать книгу Spring in action 3 edition. Но сравнивая с этим вижу много различи. Получается я зря тратил на книгу? Повосетуйте пожалуиста.
Не зря. Мои видео дополняют те знания, а не отменяют. Спринг разносторонний
Зря. Книжка абсолютно бестолковая и не годится для изучения Спринга. Лучше посмотрите видео от Тимура Батрышынова (у Романа Бровко в плейлисте есть).
как рест приложения спринг сисуриту прикрутить
Я так понимаю, что при старте app IDEA сама стартует сервер?
А как его стартануть сервер, если я использую Eclipse или NetBeans?
Не Idea, а Spring стартует встроенный (embeddable) сервер Tomcat, который подключается, когда используется зависимость spring-boot-starter-web (в gradle или maven).
Поэтому в Эклипсе достаточно просто запустить приложение на выполнение, а сервер "сам" поднимется.
*Ребята, кому не сложно - напишите плз как в постмане сделать все проверки который ЛетсКод в конце делает? (GEТ - у меня работает ,а вот остальное PUT POST и тп валится*
На Mozilla Firefox на POST запрос - "TypeError: NetworkError when attempting to fetch resource." . На Chrome все нормально.
Обьясните пожалуйста почему двойные ковычки используются? new HashMap(){{ put("id", "1"); put("text", "First message"); }}); - никогда прежде такого не встечал!!
Это объект JSON learn.javascript.ru/json . В данном случае используем его для хранения в структуре Map, не используем преобразования к строгим типам JAVA. Это сделано для простоты.
это называется double brace, используются для создания коллекций с одновременным с их объявлением (т.е. создается анонимный класс (внешние фигурные скобоки) с блоком инициализации (внутренние фигурные скобки)): javarush.ru/groups/posts/1457-double-brace-inicializacija.
@@ms_shifu7047 спасибо
Стоит ли сначала начинать с туториала по Sweater App?
По настроению
вместо index, выводится :
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
MessageController получается в спринге это синглетон?
ага. и автор показывает на примере классический race condition. а потом удивляемя откуда в продакшене у нас столько кривого кода
A для чего в Лист в качестве элемента заносится ХэшМап?
это дженерик - значит что в массиве будут хранится хэшмап объекты, поправьте если не прав
Код возврата метода Delete должен быть 200 или 204 ?
www.restapitutorial.ru/lessons/httpmethods.html
А почему метод update реализует обновление id для некоторого сообщения, а не обновление самого сообщения? ... по-моему, странная логика
id я вконце на всякий случай заапдейтил, потому как в предыдущей строке я вообще все поля обновил в записи:
messageFromDb.putAll(message);
и так, как тут можно случайно затереть оригинальный id, потому я и устанавливаю его ровно тот, что получил в URL.
Тут немного путанно, согласен. Но это времменный пример, чтобы понять rest workflow, дальше мы весь этот головняк на spring jpa переложим
Добрый день.
А как себя будет вести контролёр если в него придёт сразу 100 запросов?
Для каждого потока создаётся свой экземпляр контролера или все потоки обрабатываются одним экземпляром контролера?
Я правильно понимаю что мы получим страдное поведение от сервиса? Т к используются потоко небезопасные поля.
Было бы круто, если бы сняли видео о том как работает контролер с потоками и как делать потобезопасные контролеры.
Нормально поведёт себя. У нас не разделяемого стейта, поэтому проблем нет. Каждый запрос обрабатывается в своём потоке
Прошу прощение. Туплю походу или чего то не понимаю. Просто разобраться хочу. Если мы одновременно двумя запросами вызываем метод create, и одновременно два запроса попадают в строчку messages.put(“Id”, String.valueOf(counter++)), мы можем потерять значение в поле counter?
@@user-se1mk6xq3g а, конкретно тут, да могут быть конфликты, потому что я тут поэтапный старт описываю. Дальше мы делаем БД и там уже проблем быть не должно, ибо нет разделяемых ресурсов
Спасибо.)
Прошу не думать что умничаю или придираюсь. Хотел знать правильно ли понимаю текущую ситуацию.
Вообще крутой канал.
Буду практиковать.
почему выбрали gradle?
В Мозилле у меня не работает. "
Content Security Policy: Параметры страницы заблокировали загрузку ресурса localhost:8081/favicon.ico («default-src»). 2 FaviconLoader.jsm:174:19
fetch('/message/').then(response => response.json().then(console.log))
Promise { : "pending" }
Content Security Policy: Параметры страницы заблокировали загрузку ресурса localhost:8081/message/ («default-src»). 2 debugger eval code:1:5
TypeError: NetworkError when attempting to fetch resource. debugger eval code:1:6
"
получилось как-то решить эту проблему?
стоит ли тратить время на свитер, или можно сразу этот плейлист смотреть?
По желанию)
Привет! А как сделать такие приятные анимации всплывающих подсказок как у тебя в IDEA?