Я подумал, что вернусь к этой теме, так как я не верю, что в прошлый раз я достаточно справедлив, и я считаю, что это действительно важно при создании API, который будет использоваться не только публикой или клиентом, но и вами также !
Когда браузер запрашивает text/html
согласование с сервером. Так что на самом деле ваш веб-сайт — это API, вы Views
— просто дополнительный тип контента, который ваш API обслуживает по запросу.
пример
Допустим, вы создаете Twitter; На начальной странице показан список твитов, поэтому браузер выполняет вызов, /tweets
а сервер отвечает списком твитов, отображаемых с помощью HTML.
Как только страница загружена, клиент использует JavaScript для загрузки новых твитов, поэтому он /tweets
снова вызывает , на этот раз возвращает json
результат, и механизм шаблонов на стороне клиента затем отображает и добавляет их в верхнюю часть существующего списка, сохраняя клиента в курсе последних твитов.
Что приятно, новые данные не нужно записывать на сервер!
Примечание: я не собираюсь обсуждать API RESTful, это просто вызовет слишком много аргументов.
Нужен код пожалуйста
Хорошо, давайте посмотрим на это в действии по-настоящему. Когда я продемонстрировал это в своем предыдущем посте, я показал несколько сложные переговоры. На этот раз я собираюсь показать супер простой сценарий.
У нас есть ProductsModule
, это может Get
один продукт, или это может Get
список продуктов.
public class ProductsModule : NancyModule { public ProductsModule(IProductRepository productRepository) :base("products") { Get["/{id}"] = _ => { var product = productRepository.Get((int)_.id); return product; }; Get["/"] = _ => { var products = productRepository.List(); return products; }; } }
Используя плагин Chrome «Почтальон», который можно найти в Интернет-магазине Chrome , мы можем вызывать некоторые вызовы для получения данных. Мы указываем URL
, VERB
и добавляем некоторые заголовки. В этом случае мы добавим один заголовок. Accept
где мы указываем, что мы хотим application/xml
.
Когда мы вызываем это, мы получаем результат XML наших продуктов:
Когда мы делаем тот же вызов, но указываем Accept
заголовок, application/json
мы получаем результат в формате JSON.
Хорошо, правда? Пока что мы не написали никакого кода, кроме как возвращать некоторые данные в указанную конечную точку. Давайте посмотрим на первый маршрут, это маршрут Get By Id, и все, что мы возвращаем, это один продукт.
Теперь, если мы укажем Accept как то, что запрашивает браузер, text/html
мы ожидаем визуализированный HTML.
Бэм, мы получаем ошибку, но это только потому, что представление еще не существует. По умолчанию NancyFX ищет представление с тем же именем возвращаемого типа.
Поскольку мы вернули «продукт», имя представления, которое Нэнси будет искать, — это typeof(Product).Name
или Product
. Поэтому, если мы создадим новый вид продукта для отображения некоторых данных:
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title></title> </head> <body> <div> Id: @Model.Id <br /> Name: @Model.Name <br /> Price: [email protected] </div> </body> </html>
Супер супер просто, теперь, когда мы снова вызываем тот же маршрут, мы получаем:
Теперь у нас есть единый API, который возвращает JSON, XML или HTML.
Непростые проблемы
Вот где дела обстоят непросто: если мы хотим вернуть коллекцию с представлением, NancyFX попытается преобразовать его List<Product>
в его имя и ищет представление. В результате поиск представления по названию List`1
может показаться неудачным, но, как ни странно, на самом деле вы можете создать представление с обратной цитатой.
Итак, давайте создадим новый файл и назовем List`1.sshtml
его базовым HTML:
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title></title> </head> <body> @Each <div> Id: @Current.Id <br /> Name: @Current.Name <br /> Price: [email protected] </div> <hr> @EndEach </body> </html>
Примечание: если вам интересно, это не Razor, это Super Simple View Engine от Нэнси ?
Теперь, если мы снова запустим сайт и нажмем, /products
мы получим:
резюмировать
До сих пор мы создали одну конечную точку с очень небольшим количеством кода, который может отвечать JSON / XML / HTML. Далее я собираюсь показать, как Negotiate
дает вам больше гибкости.