Обработка запросов GET, POST, PUT и DELETE
ОБНОВЛЕНИЕ: К сожалению, мне пришлось сократить эту серию, потому что разработка Aqueduct была прекращена. Я рекомендую вам не использовать Акведук. Я верю, что появятся и другие серверные фреймворки Dart, но на данный момент явного победителя нет. А пока ознакомьтесь с моей серией статей о создании сервера Dart с нуля.
Это вторая часть из семи частей.
- "Начиная"
- HTTP-запросы (вы здесь)
- База данных
- Тестирование
- Аутентификация
- Производственный сервер
- Клиентское приложение Flutter
Вступление
На последнем уроке вы уже настроили Dart, Aqueduct и вашу IDE. Вы также сделали простой запрос GET от вашего браузера к работающему серверу Aqueduct, который вернул ответ браузеру.
В этом уроке вы узнаете еще несколько способов выполнения HTTP-запросов. В дополнение к запросам GET вы также будете выполнять запросы POST, PUT и DELETE. На стороне сервера вы напишете код для Aqueduct, который будет обрабатывать эти запросы.
Способы выполнения HTTP-запросов
Если вы предпочитаете смотреть видео, а не читать текст, то вот следующее видео:
Есть много разных способов сделать HTTP-запросы. Помимо браузера, вы можете использовать программу под названием Postman, утилиту командной строки curl, инструмент браузера под названием Swagger , среду тестирования Aqueduct или даже приложение Flutter.
Мы кратко рассмотрим каждый из них, но сначала откройте проект Aqueduct, который вы создали на последнем уроке. В файле lib / channel.dart замените метод entryPoint()
следующим кодом:
@override Controller get entryPoint { final router = Router(); router.route("/example").linkFunction( (request) async { return Response.ok('Hello world') ..contentType = ContentType.text; }, ); return router; }
Примечания:
- Я изменил ответ, чтобы он возвращал
Hello world
в виде обычного текста, а не в формате JSON. - Путь для маршрута по-прежнему
/example
.
Теперь запустите сервер, выполнив следующую команду в терминале, когда вы находитесь в корне своего проекта Dart.
aqueduct serve
Браузер
Откройте любой браузер и перейдите по следующему адресу:
http://localhost:8888/
Aqueduct должен вернуть ответ 404 Not Found, потому что вы не обработали /
корневой маршрут. Теперь перейдите по маршруту, который вы определили:
http://localhost:8888/example
Вы должны получить Hello world
ответ.
Успех в браузере.
Почтальон
Адресная строка браузера подходит только для выполнения базовых запросов GET, но вам также потребуется выполнять другие запросы. Почтальон - удобная программа для этого. Это будет ваш основной инструмент для выполнения HTTP-запросов в этой серии.
Скачайте Почтальон здесь. Если вы продолжаете нажимать на ссылку, вам не нужно ни для чего регистрироваться. После того, как вы его загрузили, установите его.
Введите следующее в адресной строке Postman и нажмите Отправить.
localhost:8888/example
Вы должны получить ответ от Aqueduct, показывающий Hello world
в теле.
Обратите внимание, что статус - 200 OK
. Все хорошо с сервера.
Успех с почтальоном.
завиток
Curl - мощная утилита командной строки. Иногда у вас нет графического интерфейса для выполнения запросов (например, когда вы находитесь на сервере), поэтому наличие такого инструмента может быть очень полезным.
Откройте терминал и выполните следующую команду, чтобы узнать, установлен ли у вас curl:
curl --version
Если он у вас не установлен, пропустите этот раздел. Мы не собираемся его так часто использовать. Но если вы хотите его установить, официальный сайт находится здесь.
Чтобы сделать запрос GET, выполните следующую команду:
curl -X GET "http://localhost:8888/example"
Вы должны получить Hello world
ответ.
Успех на локон.
Чванство
Swagger, который теперь называется OpenAPI, позволяет вам протестировать серверное приложение, создав клиентское приложение в браузере. На самом деле я пока не нашел его настолько полезным, поэтому я не буду вдаваться в подробности о том, как его использовать сейчас.
Если вам интересно, то здесь - это официальная страница, а здесь - это документация по Акведуку.
Фреймворк для тестирования акведуков
Среда тестирования Aqueduct - хороший способ делать HTTP-запросы. В Части 4, посвященной тестированию, вы сделаете гораздо больше, но давайте сделаем небольшой предварительный просмотр прямо сейчас.
В своем проекте откройте файл test / example.dart.
Щелкните код правой кнопкой мыши, чтобы открыть контекстное меню. Выберите Выполнить или нажмите Control Shift R.
Тест не пройден, поскольку ожидается, что тело будет {“key”: “value”}
. Но мы уже поменяли тело на Hello world
. Тест необходимо обновить.
Замените весь файл следующим кодом:
import 'harness/app.dart'; Future main() async { final harness = Harness()..install(); test("GET /example returns 200 {'key': 'value'}", () async { expectResponse( await harness.agent.get("/example"), 200, body: "Hello world", ); }); }
Запустите тест еще раз, и он должен пройти.
Выполнение запроса с помощью тестовой среды Aqueduct выполнено успешно.
Приложение Flutter
Я говорю «приложение Flutter», но это может быть приложение для Android или iOS. Вы можете использовать любой из этих вариантов для выполнения HTTP-запросов.
В части 7 мы будем создавать приложение Flutter, но если вы хотите сначала протестировать сервер, вы можете это сделать.
Вы делаете HTTP-запросы во Flutter, используя пакет http. Подробнее об этом вы можете прочитать в следующей статье:
Обработка запросов GET
Сервер уже обрабатывает GET-запросы к маршруту /example
, но сейчас мы собираемся его расширить.
В этой серии статей вы собираетесь создать приложение-словарь, поэтому вместо /example
вы собираетесь определять маршрут с путем /words
.
В lib / channel.dart замените метод entryPoint()
следующим:
@override Controller get entryPoint { final router = Router(); router.route("/words").link(() => WordsController()); return router; }
Обратите внимание на следующее:
- Маршрут
/words
. - Вместо
linkFunction
мы используемlink
. Это перенаправляет все запросы, поступающие к/words
, классу контроллера. Это сохраняет код нашего маршрутизатора чистым. - Вы еще не прошли
WordsController()
курс. Вы сделаете это дальше.
Создать контроллер
В папке lib создайте подпапку с названием controller.
Затем в lib / controller создайте файл с именем words_controller.dart. Вставьте следующий код:
import 'package:dart_server/dart_server.dart'; class WordsController extends ResourceController { final _words = [ {'word': 'horse'}, {'word': 'cow'}, {'word': 'camel'}, {'word': 'sheep'}, {'word': 'goat'}, ]; @Operation.get() Future<Response> getAllWords() async { return Response.ok(_words); } }
Примечания:
- Этот класс расширяет
ResourceController
, который является классом Aqueduct, который заботится о многих деталях обработки запросов. - У нас еще не настроена база данных, поэтому для данных мы пока будем использовать массив объектов карты.
@Operation.get()
- это аннотация, которая сообщает Aqueduct, что этот метод будет обрабатывать запросы GET. Он возвращаетResponse.ok()
, который является ответом200 OK
, и мы передаем в него список данных. Aqueduct автоматически преобразует его в строку JSON и поместит в тело ответа.
В lib / channel.dart импортируйте только что созданный класс.
Протестируйте свой новый контроллер
Остановите сервер, нажав Control + C. Затем перезапустите сервер:
aqueduct serve
Откройте Postman и сделайте запрос, как мы делали раньше, но на этот раз измените адрес на следующий:
localhost:8888/words
Когда вы нажмете «Отправить», вы должны увидеть список JSON в теле ответа:
Получение одного предмета
В настоящее время сервер возвращает весь список данных. Что, если вы хотите получить только один элемент данных? Обычный способ сделать это - добавить идентификатор к пути следующим образом:
localhost:8888/words/1
Это запрос слова с id=1
от сервера, но мы еще не обрабатываем его.
Откройте lib / channel.dart. Замените метод entryPoint()
следующим:
@override Controller get entryPoint { final router = Router(); router.route("/words/[:id]").link(() => WordsController()); return router; }
Примечания
- Теперь к
/words
пути добавлен/[:id]
. - Двоеточие
:
означает, чтоid
- это переменная. Вы можете называть переменную как хотите. - Квадратные скобки
[ ]
означают, что переменная не является обязательной.
Вернитесь в lib / controller / words_controller.dart. Вы собираетесь создать новый метод для обработки запросов на отдельные элементы. Вставьте следующий метод под методом getAllWords()
.
@Operation.get('id') Future<Response> getWordByID(@Bind.path('id') int id) async { return Response.ok(_words[id]); }
Примечания
- Знак
'id'
в аннотации служит для того, чтобы отличать этот метод от метода plain@Operation.get()
, который мы создали ранее. Здесь'id'
- это то же имя, которое мы использовали для нашей переменной в channel.dart. - Часть
@Bind
означает, что Aqueduct возьмет переменную пути'id'
и попытается преобразовать ее какint
. Если приведение не увенчалось успехом, Aqueduct вернет404 Not Found
. Но в случае успеха вы можете использовать целое число в качестве индекса для возврата элемента из списка данных.
Перезагрузите сервер:
aqueduct serve
В Postman отправьте запрос GET со следующим адресом:
localhost:8888/words/1
Вы должны получить ответ с одним элементом в теле:
Был возвращен элемент с индексом 1
. Успех! Вы можете поиграть с запросом GET, отправив разные значения индекса. Если вы выберете большое значение, это вызовет ошибку сервера, и Aqueduct выдаст ответ 500.
Обработка запросов POST, PUT и DELETE
В этом разделе мы просто собираемся создать методы для обработки запросов POST, PUT и DELETE. Поскольку эти запросы предназначены для изменения данных на сервере, мы не закончим их до третьей части, когда добавим базу данных.
В lib / controller / words_controller.dart добавьте следующие методы к классу WordsController
.
@Operation.post() Future<Response> addWord() async { return Response.ok(null); } @Operation.put('id') Future<Response> updateWord(@Bind.path('id') int id) async { return Response.ok(null); } @Operation.delete('id') Future<Response> deleteWord(@Bind.path('id') int id) async { return Response.ok(null); }
Примечания
- Аннотация
Operation
определяет тип запроса, который обрабатывает метод. Запросы POST предназначены для создания ресурса сервера. Запросы PUT предназначены для обновления существующего ресурса. DELETE был назван правильно, поэтому требует пояснений. - Поскольку PUT и DELETE работают с существующими данными, мы привязываем идентификатор к целому числу, чтобы определить, какой элемент данных следует обновить или удалить.
- На данный момент все возвращает ответ по умолчанию
200 OK
. Мы изменим это позже.
Перезагрузите сервер с aqueduct serve
.
Проверьте это в Postman
Откройте Почтальон. Вместо GET выберите POST в раскрывающемся меню.
В качестве URL-адреса запроса напишите следующее, а затем нажмите Отправить.
localhost:8888/words
Вы должны получить 200 OK
ответ.
Повторите этот процесс для PUT и DELETE, используя URL-адрес с идентификатором:
localhost:8888/words/1
Результат все равно должен быть 200 OK
.
Полный код
Если вы заблудились, вот полный код того, что мы сделали сегодня.
lib / channel.dart
библиотека / контроллер / words_controller.dart
Заключение
Теперь вы знаете основы обработки любого типа запроса. Конечно, позже будет еще что заполнить, но, как видите, это не так уж и сложно. В этом уроке путь маршрута был /words
. Вы можете легко обрабатывать другие маршруты, просто определив какой-либо другой путь и назначив новый контроллер, который позаботится о нем.
В части 3 вы узнаете, как подключить базу данных PostgreSQL к серверу Aqueduct.
После того, как я закончу часть 3, я добавлю сюда ссылку. А пока не стесняйтесь продолжать смотреть видеоряд или следовать документации по акведуку.