Здравствуйте, Cyberax, Вы писали:
C>Да, это плохо. Все ограничения и способности API должны быть описаны в его схеме. По факту в REST это совсем не так.
По факту это никогда не так. Схема описывает только маленький кусочек поведения API. Тут по соседству обсуждали вопросы тестирования — я там иллюстрацию приводил.
C>Например, имеем вот это API: https://docs.docker.com/engine/api/v1.41/#operation/ContainerArchiveInfo — "взять архив файловой системы".
Нет, "взять архив файловой системы" — это
https://docs.docker.com/engine/api/v1.41/#operation/ContainerArchive. А то, что вы показали — это "взять информацию об архиве файловой системы".
C>Внимание, вопрос! Как это API будет взаимодействовать с Range?
Тот, который вы указали — никак. Запрос HEAD не поддерживает хидер Range
Зато вызвав HEAD, мы получим (или не получим) заголовок Accept-Ranges, который скажет всё, что нам надо знать.
А можем просто сразу сделать GET запрос с Range.
Если сервер не умеет в Range, то он просто вернёт полный файл.
При этом мы никогда не перепутаем частичный респонс с полным — поэтому у нас корректно работают любые комбинации клиента и сервера.
C>Не видел пока вообще ни одного API, где был бы conditional get. Более того, я даже не видел клиентов, которые его бы поддерживали.
Любой браузер и любой прокси-сервер.
C>Так что на практике получается, что всё преимущество REST API заключается ровно в одном сценарии с выдачей статических файлов, и может быть реализована только при использовании клиента, который специально написан для этого.
Отчего же "статических"?
C>>>Не будут. Делаем нужные параметры запроса явным параметром и всё. Для примера, если что-то типа DownloadFile, то в запрос добавляем опциональные поля типа Range и прочих. В качестве бонуса, не нужно заниматься разбором формата Range.
S>> Покажите мне реальный (g)RPC API в котором есть опциональные параметры типа Range и прочих.
C>То есть? Это будет просто параметр в API.
C>Типа:
C>C>service FileService {
C> rpc DownloadData(in DownloadDataRequest) returns (stream DataChunk);
C>}
C>message DownloadDataRequest {
C> message ChunkRange {
C> uint64 offset = 1;
C> uint64 size = 2;
C> }
C> string file_id = 1;
C> repeated ChunkRange chunks = 2;
C>}
C>message DataChunk {
C> uint64 chunk_index = 1;
C> uint64 offset = 2;
C> uint64 size = 3;
C> bytes data = 4;
C>}
C>
Пример такого gRPC API в живой природе можно увидеть?
C>По API сразу понятно что и как использовать. Не надо гадать: "А поддерживает ли API-сервер Range?"
При желании, так можно сделать и в REST. Например, многие протоколы вместо Range:items поддерживают явные параметры size и page.
А можно просто
пробовать, что поддерживает сервер. Например, если мы получили частичный ответ, а потом соединение упало, то мы можем попытаться запросить недостающую часть.
Не умеет сервер так — ну ок, перевыкачаем целиком. Умеет — сэкономим трафик.