REST API и предоставление двоичного ресурса

Каково соглашение о доставке двоичного ресурса (например, файла pdf) с помощью REST API? Вы просто возвращаете URL-адрес ресурса в своем ответе JSON или XML, например, {"url": "http://example.com/document.pdf"}?

Я пытаюсь понять разницу между URI и URL-адресом и придерживаться философии RESTful. По общему признанию, это ново для меня, поэтому я могу не понимать некоторые вещи.

Ответ 1

В этом разделе предполагается, что вы имеете в виду: как я могу сообщить пользователю, где найти бинарный ресурс

Разница между URI и URL-адресом не имеет ничего общего с бинарными и недвоичными типами данных (см. Также).

Если вы возвращаетесь в основном в JSON, то url является обычным способом. Если вы делаете что-то большее, чем HTML/XML-ish, то что-то вроде элемента <link> с хорошим rel имеет большой смысл.

Очевидно, что если клиент делает запрос GET на прямой URL-адрес, который вы им дали, вы должны отправить им файл, если только они не отправили кучу заголовков согласования контента, которые фактически не позволяют вам выполнить свой запрос. В этом случае 406 Not Acceptable ответ 406 Not Acceptable (или официальное определение) имеет большой смысл.

Если вы имеете в виду что-то еще по вашему вопросу, пожалуйста, уточните.

Рамблинг "Сделай это как этот" раздел

Во-первых: игнорировать URL-адрес и URI. Это не имеет никакого отношения к этому. Вообще.

Далее: Если ваша проблема не связана с "Как мне привязать к ресурсу" (на который может повлиять материал, который я собираюсь обсудить), но "Что, если мой ресурс - это просто файл PDF", у вас есть все виды варианты его решения. Во-первых, вам нужно отступить и подумать более абстрактно (немного). Ваш ресурс почти наверняка не является "файлом PDF". Это "файл, загруженный пользователем", или "PDF-версия отчета, который я генерирую" и т.д.

В первом случае у вас, вероятно, нет никакого представления ресурса за пределами двоичного файла, который они вам отправили, что совершенно нормально. Вам, вероятно, не потребуется выполнять какие-либо переговоры по контенту, когда вы получаете GET для URL-адреса этого ресурса. Просто отправьте им файл, с учетом предостережений о 406 о котором я упоминал выше.

Во втором случае у вас могут быть все виды представлений этого ресурса: CSV, HTML, LaTeX, вы называете это. В этом случае, когда вы получаете GET для URL-адреса ресурса, вам нужно выполнить некоторое согласование контента, чтобы вы знали, отправлять ли его документ PDF или что-то еще. Возможно, у вас может быть JSON-представление ресурса, являющегося просто исходными данными, которые вы используете для создания PDF файла.

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

Наконец, как @monitorjbl говорит: вы, вероятно, не хотите вставлять двоичные данные непосредственно в текстовый формат, такой как JSON или XML. Есть способы сделать это, часто используя слова "base64-encoded", но обычно это не самый лучший подход. В общем, вы не должны смешивать двоичные данные и текстовые данные.

Ответ 2

Двоичные или нет, ваши ресурсы REST должны быть описаны с помощью типов гипермедиа.

  • если ваши REST-клиенты PUT/POST-ресурсы в формате msgpack, сервер REST может прочитать это сообщение и обновить/создать ресурс. Так почему бы не.
  • если ваши ресурсы REST-клиентов PUT/POST в формате PDF, я думаю, вы не сможете извлечь всю необходимую информацию для правильного создания/обновления ресурса. Итак, нет.

В этом последнем случае вы можете иметь дело с сервисом "Google диск" -like: эти файлы PDF не являются вашими ресурсами как таковыми и должны быть связаны вашим фактическим ресурсом (т.е. URL-адрес должен быть в вашем ресурсе).

Даже если Google Диск не может быть идеальным API REST (ссылка на API), он имеет дело как с ресурсами JSON, так и с фактическими двоичными файлами.

Ответ 3

По моему опыту, это противоречило бы идее веб-службы REST. Вы никогда не можете кэшировать этот ответ без серьезной головной боли, в отличие от традиционно RESTful-сервисов. Кроме того, поскольку вам нужно будет использовать службу как текст, чтобы читать XML/JSON, вы, вероятно, не сможете оптимизировать как текстовые, так и двоичные чтения. Не говоря уже о том, что вам всегда понадобится бинарная информация, или вы получите довольно значительный удар по производительности, когда вам нужны только текстовые данные. И если вам всегда нужны бинарные данные, можете спросить себя, зачем вам нужен веб-сервис?

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

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