WeatherForecast. Сервисы. Dev.
Предисловие
Мы начали с простенького веб-приложения и разобрали базовые шаги в его публикации. Теперь пришло время немного усложнить наш учебный пример. В наши дни реальные проекты редко (читай "никогда") состоят только из одного сервиса, тем более когда так модны "микросервисы". Поэтому дальше мы разберемся как разрабатывать и публиковать много-модульные/сервисные проекты.
Поехали
Как всегда, код тут.
Нашему незамысловатому проекту нужна функциональность, которую мы могли бы вынести в отдельно стоящий сервис. Давайте показывать "рекламу", когда пользователь узнает погоду. При этом содержание рекламы будет зависеть от введенного города. Назовем этот сервис Ads.
Я для удобства создам новый проект в том же solution, но представляя себе, что это два разных "микросервиса", сделаю их код не зависимым друг от друга. Так бы и произошло, если бы реальный большой проект разрабатывался несколькими команда, каждая из которых отвечала за определенные микросервисы (или только один). Для наглядности я разложу проекты по папочкам Ads и WeatherForecast:
Для сервиса Ads мне понадобятся два проекта:
DeployToProduction.Ads.Core - Library проект, в котором у нас будет код моделек
AdPost и AdRequest - простые Data Transfer Object (DTO) классы сериализуемые в JSON.
DeployToProduction.Ads.WebApi - ASP.NET Core Web API проект, который предоставит end-point для получения объектов AdPost по запросу с аргументом AdRequest.
Данные для сервиса пока для простоты мы "захардкодим". Контроллер для обработки запроса:
Уберем лишнее из настроек запуска и отключим открывание браузера при старте проекта:
Нужно запустить и протестировать новый сервис. Делаем его в панели отладки активным
Для тестирования "апишек" сегодня есть много инструментов, один из самый популярных - Postman.
Я предпочитаю использовать расширение для VS Code под названием REST Client из-за его простоты. Достаточно создать файл с расширением http и простым синтаксисом описать запросы. В редакторе появятся "кнопочки" Send Request, и теперь можно вручную выполнить проверку:
Файл web-api.http лежит в каталоге Test.
Теперь модифицируем приложение WeatherForecast. Помним, что проекты сервисов по нашей задумке должны быть независимыми, поэтому нам нужны копии моделек:
Создадим сервис, который будет отправлять запрос:
Первое, timeout запроса должен быть. Практически всегда его выносят в настройки (конфигурационные файлы), чтобы настраивать под конкретные условия (скорость сети, нагрузка). Дефолтные 180 секунд не годятся. Пользователь не будет ждать. Если сервис не критичен для приложения, то есть он не отвечает, тогда "идем" дальше без него. Такие моменты нужно изначально продумывать в архитектуре приложения.
Второе, обработка ошибок. Ловим, оборачиваем в "свои" специфичные классы ошибок, добавляем контекста, информации, которая потом поможет при диагностике проблем. Это очень сложная тема, которая требует опыта, понимания и интуиции, что, где, как пойдет не так, и какая информация пригодится.
Добавляем свойство AdPost в модель страницы и делаем запрос к нашему сервису:
Нам понадобится добавить в настройки url сервиса Ads:
Настроим контейнер внедрения зависимостей:
Visual Studio позволяет нам во время разработки запускать и отлаживать несколько проектов, для этого нужно открыть свойства Solution:
Открываем раздел Common Properties -> Startup Project:
Выбераем Multiple startup projects, установливаем Action в значение Start для проектов DeployToProduction.Ads.WebApi и DeployToProduction.WeatherForecast.App, жмем ОК:
Помним, что для работы нашего приложения нужны баз данных, поэтому запускаем контейнеры:
docker run --name weather-forecast-postgres -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d postgres docker run --name weather-forecast-redis -p 6379:6379 -d redis
Теперь запускаем наши сервисы:
З.Ы.
Конечно же вы помните, что "тру" разработчики проверяют свой код автоматическими тестами. Пока вы в творческом цикле пишу-пробую инструменты ручного тестирования могут быть вам удобней, но готовый код - это код покрытый авто-тестами. Поэтому к тестированию сервиса Ads мы ещё вернемся. ;)