2015-01-29 3 views
0

Я разрабатываю REST API, где один из моих вызовов выглядит как /api/1/orders/1234. Результат возвращается в формате Json по умолчанию и отображается в окне браузера с помощью AngularJS.Отчеты REST и PDF

В этом конкретном случае я должен создать PDF-версию ресурса, которая будет напечатана, подписана (вручную) и сохранена для юридических целей. Каков рекомендуемый способ сделать это, учитывая, что этот вызов содержит все данные, необходимые для создания отчета?

Я полагаю, что версия PDF - это просто другой формат ресурса, и просто добавить параметр запроса (?format=pdf) должно быть достаточно и не так уродливо. Есть ли лучший способ (не важно, сложнее или проще реализовать, особенно на стороне сервера) ?.

Я не мог найти рекомендованный способ сделать это в любом месте, поэтому любой намек был бы хорошим. Извините, если этот вопрос слишком велик, «вопрос, основанный на мнениях».

+0

content-type: application/pdf –

+0

@WonTonSoup Нет, 'Content-Type' указывает MIME тела запроса/ответа. Возможно, вы имели в виду 'Accept', но проблема в том, что некоторые клиенты не поддерживают пользовательские поля' Accept'. –

ответ

1

«Правильный» способ будет использовать поле заголовка запроса Accept: application/pdf, которое позволяет вести переговоры по содержанию.

Ваше предложение о api/1/orders/1234?format=pdf может работать, хотя есть немного чище решение api/1/orders/1234.pdf

В зависимости, если у вас есть контроль над клиентами или нет, (я пишу мой клиент Perl CLI, а) я бы не беспокоился те, которые не поддерживают полные спецификации HTTP. Пока мы чувствуем себя обязанными поддерживать дрянных клиентов, не будет никакого желания обновлять этих клиентов.

1

Рекомендуемый способ справиться с такой ситуацией - использовать content negotiation.

Когда ответы передают информацию полезной информации, сервер происхождения часто имеет различные способы представления этой информации; например, в различных форматах. По этой причине HTTP предоставляет механизмы для согласования содержимого .

Apache HTTPD content negotiation documentation содержит несколько хороших примеров (вы можете игнорировать детали конфигурации, если вы не используете httpd). Это будет хорошо работать, если вы используете API для клиентов приложений.

Таким образом, когда клиент хочет представление JSon, он может запросить

GET /api/1/orders/1234 HTTP/1.1 
Host: example.org 
Accept: application/json 

и когда клиент хочет представление PDF, он может запросить

GET /api/1/orders/1234 HTTP/1.1 
Host: example.org 
Accept: application/pdf 

Однако, ситуация немного меняется если клиенты - это в основном браузеры, потому что они обычно отправляют общий заголовок Accept при вводе URL-адреса в адресной строке. Вы можете проверить эти значения для обычных браузеров, таких как Firefox, Safari, Chrome, Internet Explorer и Opera here.

Например, Chrome отправляет следующий заголовок Accept.

Accept: application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5 

Таким образом, в этом случае, что браузер говорит, что он предпочитает XML и HTML, если не простой текст, PNG изображения или любые другие типы. В этом случае он не говорит о каких-либо предпочтениях ни в json, ни в pdf (и пользователь не может легко указать, что с помощью браузера).В этом случае было бы разумно иметь два URL-адреса, например/api/1/orders/1234 (или /api/1/orders/1234.json) и /api/1/orders/1234.pdf.

Таким образом, ваш выбор будет зависеть от того, какого типа клиентов вы ожидаете. Однако, если это два представления одного и того же ресурса, более подходящий способ сделать это с использованием HTTP будет заключаться в использовании согласования контента.

Смежные вопросы