Загрузка текста, изображений и файлов через REST API

#java #spring #api #rest #http

Вопрос:

Проблема, с которой я на самом деле сталкиваюсь, заключается в том, чтобы создать запрос на звуковую дорожку и отправить его через REST API. Это не было бы проблемой, но данные находятся в разных форматах:

  1. Информация о треке (название трека, тип музыки, имя автора и т.д.) — только текст
  2. Обложка альбома этого трека (JPG, png и т.д.) — изображение
  3. Содержимое трека (формат mp3 и т.д.) — аудио (двоичный) файл

Вопрос в следующем: должны ли все эти данные передаваться в одном запросе?

На мой взгляд, все три типа данных должны быть отправлены в три разных запроса и в три разные конечные точки, но, возможно, есть лучший способ

Я был бы очень благодарен за все ответы 🙂

Ответ №1:

Это зависит от того, как ваша модель данных определена в разрабатываемой вами службе REST, и от предлагаемых вами функций.

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

  • POST /audiotracks : Создайте ресурс звуковой дорожки. Метаданные-это содержимое ресурса, скорее всего, в формате JSON.
  • POST /audiotracks/{trackId}/albumcover : Опубликуйте файл обложки альбома в виде строки в кодировке Base64.
  • POST /audiotracks/{trackId}/content : Публикуйте содержимое трека в виде строки в кодировке Base64.
  • GET /audiotracks/{trackId} : Извлеките метаданные аудиотрека.
  • GET /audiotracks/{trackId}/albumcover : Принеси обложку альбома.
  • GET /audiotracks/{trackId}/content : Извлеките содержимое трека.
  • и т.д.

Ответ №2:

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

Гибкий подход может заключаться в определении Track сущности с операциями CRUD, в которых Update будут допускаться два режима PUT обновления всего содержимого (например, если в запросе нет звука, он будет удален) и PATCH частичного обновления.

Более или менее ваше определение API может следовать (в стиле REST):

  • POST /track создайте новый трек, запрос может содержать или не содержать всю информацию.
  • DELETE /track/{id}
  • PUT /track/{id} обновите всю информацию о треке (такую же, как DELETE и POST раньше, но {id} оставшуюся).
  • PATCH /track/{id} обновите информацию о треке, никакая предоставленная информация не будет удалена.
  • GET /track/{id} верните всю модель целиком.
  • GET /track/{id}/projectionX где projectionX находятся любые необходимые вам запросы/проекции (только аудио, только общая информация, составленное/закодированное аудио)

Но, если в вашем бизнесе одна обложка альбома будет повторно использоваться несколькими треками, вам следует определить эту новую сущность аналогичным образом и изменить Track модель, чтобы она содержала только ссылку на «обложку альбома» (а не само изображение).

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

Например, если вы определяете /audiotracks/{trackId}/albumcover изменение в отношениях между моделями данных (например, добавление Album сущности), вам необходимо изменить не только все модели данных, но и вызовы API и рабочие процессы.

В любом случае, развивайте свой API только в соответствии с новыми бизнес-требованиями.

Комментарии:

1. В этом случае модель трека проста. Обложка альбома имеет отношение 1 к 1 с треком (существует гораздо больше сущностей, чем я упоминал, но вы правы, разделяя «общие» данные на другую сущность). В этом случае ответ Луи, вероятно, наиболее близок к тому, что я хочу получить. Спасибо вам 🙂

2. Как я уже отмечал, я считаю неправильным использовать POST /audiotracks/{trackId}/albumcover , если обложка альбома представляет собой данные одной и той же сущности ( AudioTracks в данном случае), вы связываете структуру вызовов API и рабочий процесс с вашим представлением модели данных (т. Е. Вы заставляете делать и знать! много звонков, когда требуется только один). ИМХО.

3. (т. е., если завтра у вас будет несколько обложек альбомов, вы ДОЛЖНЫ изменить все вызовы api и рабочие процессы , используя мой подход, только те, кто и когда хочет использовать несколько обложек альбомов, просто должны изменить любой набор обложек альбомов mytrack.albumdata.cover = xxx , никаких изменений в вызовах, рабочих процессах,…)