- PVSM.RU - https://www.pvsm.ru -
Здравствуйте, дамы и господа. Подумалось, в нашей пятничной рубрике еще не было ни одной дельной статьи о надувных динозаврах в контексте гостиничного бизнеса.
Если вдруг вас совсем не интересует фреймворк NancyFX и микросервисы на платформе .NET, создаваемые с его помощью — почитайте про динозавров!
Наш офис ни с чем не перепутаешь — у нас тут установлены надувные динозавры, целый парк видавших виды мониторов, а весь коллектив постоянно гоняет йоркширские чаи. Но, чтобы уделять на такой живительный размандык то время, которого он, безусловно, заслуживает, мы должны быстро и эффективно решать наши основные задачи – в частности, поддерживать сервис, при помощи которого наши клиенты могут бронировать гостиничные номера.
Чтобы это получалось еще лучше, мы постепенно переделали наш сегмент базы кода под микросервисную архитектуру [1]. Первым делом мы написали API Reservations, выделив весь функционал, связанный с созданием и извлечением записей о бронировании в отдельный домен с независимыми системами версионирования, релизов и обслуживания. Так нам удалось без труда поддерживать новые кроссплатформенные фронтенды – например, мобильную версию и форму бронирования на основе Node.js
Но затем мы пошли далее и выделили такие этапы бронирования (например, отправку сообщений с подтверждениями), которые не обязательно должны осуществляться строго до того, как подтверждение будет возвращено на фронтенд. Сам процесс бронирования можно свести к двум наборам действий: заказываем номер в отеле и сохраняем соответствующую запись, если можем быть уверены, что после этого обе операции будут выполнены максимально оперативно. Для этого мы добавили в наш инструментарий очереди сообщений и задействовали набор процессоров команд и событий, предназначенных как раз для обработки таких внеполосных задач.
Вскоре нам понадобился набор сервисов, каждый из которых отвечал за конкретную часть домена. Чтобы их разработать, нам потребовалось быстро и легко написать REST API, желательно без пробуксовки. Вот тогда мы и нашли Nancy.
NancyFx [2] – потрясающий легкий веб-фреймворк для .NET. Если вы ориентируетесь во фреймворках для других языков, например, Sinatra и Express, то уже вполне представляете, что от него ожидать. С другой стороны, если знакомы лишь с такими .NET-глыбами как Microsoft MVC и WCF, то, вполне возможно, вас ждет приятный сюрприз.
Вместо того, чтобы распевать дифирамбы Nancy (я это могу делать часами), лучше продемонстрирую вам, насколько проще пареной репы написать на Nancy простейшую оконечную точку в стиле REST менее чем за 15 минут.
Шаг 1: Создаем консольное приложение на C#
Разумеется, это можно сделать и на другом языке для платформы .NET. Даже на VB.
Шаг 2: Импортируем Nancy
Nancy предоставляется в виде пакетов Nuget, так что рекомендую воспользоваться менеджером пакетов Visual Studio – самым удобным инструментом для импорта двоичных файлов в проект и ссылки на них. В данном случае нам понадобится пакет Nancy.Hosting.Self
, зависящий от основного пакета Nancy.
Шаг 3: Создаем хост Nancy
В методе Main
(или эквивалентной входной точке программы) напишите:
using (var host = new NancyHost(new Uri("http://localhost:1234"))
{
Console.ReadKey();
}
Вы уже создали консольное приложение, которое слушает HTTP на порте 1234. На самом деле, нам нравится так делать, это простая реализация обратных прокси, передающих внешние HTTP-запросы управляемому процессу. Однако, Nancy поддерживает и OWIN, традиционный IIS-хостинг.
Шаг 4: Создаем маршрут к ресурсу
Создаем наш первый маршрут, наследуя класс Module
из Nancy. Напишите вот это в файле с новым проектом:
class Dinosaur
{
public string Name { get; set; }
public int HeightInFeet { get; set; }
public string Status { get; set; }
}
class DinosaurModule : NancyModule
{
private static Dinosaur dinosaur = new Dinosaur()
{
Name = "Kierkegaard",
HeightInFeet = 0,
Status = "Deflated"
};
public DinosaurModule()
{
Get["/dinosaur"] = parameters => dinosaur;
}
}
При запуске хоста Nancy просматривает вашу сборку и ищет в ней классы, наследующие NancyModule
. Они будут инстанцироваться всякий раз при поступлении запроса, обеспечивать маршрутизацию и действия. В данном случае мы создаем простой маршрут GET в конструкторе модуля и пользуемся лямбда-выражением, при помощи которого возвращаем определенный нами объект модели. Если вызвать localhost [3]:1234/dinosaur без заголовка с типом содержимого, то модель динозавра придет нам в формате JSON. Запустите приложение, попробуйте.
Шаг 5: Добавляем операцию записи
До сих пор наш ресурс был только для чтения. Добавьте в конструкторе DinosaurModule
такой код:
Post["/dinosaur"] = parameters =>
{
var model = this.Bind<Dinosaur>();
dinosaur = model;
return model;
};
Привязка принимает тело HTTP-запроса и пробует ассоциировать его с заданным типом модели. Попытайтесь послать следующий код на localhost [3]:1234/dinosaur, тип содержимого — application/json:
{
"name": "Kierkegaard",
"heightInFeet": 6,
"status": "Inflated"
}
Тело запроса следует привязать к классу Dinosaur
и присвоить нашему статическому члену Dinosaur
. Как и в случае с конечной точкой Get
, мы возвращаем модель, после чего Nancy сериализует модель JSON. В Nancy есть такие возможности как обсуждение содержимого и рендеринг представления, но в данном демонстрационном примере нам вполне подойдет поведение, задаваемое по умолчанию.
Шаг 6: Создаем и возвращаем индексированные ресурсы
Как правило, когда мы пишем REST API, нам требуется по несколько от каждого ресурса. Давайте немного модифицируем класс:
public class DinosaurModule : NancyModule
{
private static List<Dinosaur> dinosaurs = new List<Dinosaur>()
{
new Dinosaur() {
Name = "Kierkegaard",
HeightInFeet = 6,
Status = "Inflated"
}
};
public DinosaurModule()
{
Get["/dinosaurs/{id}"] = parameters => dinosaurs[parameters.id - 1];
Post["/dinosaurs"] = parameters =>
{
var model = this.Bind<Dinosaur>();
dinosaurs.Add(model);
return dinosaurs.Count.ToString();
};
}
}
Теперь маршрут - /dinosaurs
. Объект parameters
в лямбда-выражении – это, в сущности, динамический тип, комбинирующий значения из маршрута, строки запроса и тела запроса. Определяя параметр {id}
в рамках маршрута, можно захватывать его, а потом с его помощью извлекать нужный нам ресурс.
По маршруту отправки можно и дальше постить динозавров и добавлять их в коллекцию. В данном демонстрационном примере мы просто возвращаем индекс созданного ресурса как строку в теле отклика. Возможно, вы предпочтете возвращать навигационную ссылку на свежий ресурс, чтобы пользователь мог без труда к нему обращаться.
Шаг 7: Ваш ход
В финале нашей весьма обзорной экскурсии у нас получилась такая спартанская оконечная REST-точка. А что дальше? Естественно, мы хотим держать наши ресурсы в каком-то долговременном хранилище данных, а не в памяти, но что насчет валидации, обработки ошибок, безопасности?
При всей легкости и простоте Nancy прямо «из коробки» решает и многие подобные вопросы, а также предоставляет другие возможности, которые вы сможете с легкостью внедрить в проект.
Итак, общее представление о Nancy вы составили – а теперь почитайте документацию [4].
Автор: Издательский дом «Питер»
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/c-2/224832
Ссылки в тексте:
[1] микросервисную архитектуру: http://martinfowler.com/articles/microservices.html
[2] NancyFx: http://nancyfx.org/
[3] localhost: http://localhost
[4] документацию: https://github.com/NancyFx/Nancy/wiki/Documentation
[5] Источник: https://habrahabr.ru/post/318334/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.