2016-06-27 2 views
0

Я пытаюсь создать RESTful API для передачи данных в интерфейсное JS-приложение, а в будущем - родное мобильное приложение, когда я начну его писать.RESTful API - обработка обновлений, зависящих от других обновлений.

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

У меня есть две сущности, лиги и игроки. В лиге есть коллекция игроков, и когда результат вводится, игроки переключают «позицию» в лиге, если победитель оказался ниже проигравшего до того, как был введен матч.

Стандартный REST API может иметь конечные точки, как следует, чтобы обновить данные конкретного игрока в лиге:

(POST/PATCH) -/API/v1/лиги/{лигой ID}/игроков/{player-id}

eg/api/v1/лиги/1/players/12

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

Единственное другое решение, о котором я могу думать, это иметь другую конечную точку с соответствующим именем, которая принимает объект «результат», выполняет ли логика разработки новой позиции игроков на стороне сервера, соответственно обновляет и возвращает некоторые данные для пользовательского интерфейса для повторной привязки и обновления.

Итак, мой вопрос: какой из двух описанных выше методов вы выбрали бы и почему?

Если вы выберете последнее, какие данные вы вернете из вызова API для пользовательского интерфейса для привязки? Полная лига данных игрока? Или только два игрока, которые были обновлены?

Благодаря

+0

«Идентификатор игрока» - это элемент в URL-адресе, а не его текущая позиция или рейтинг в лиге. Ваш URL должен всегда указывать на тот же ресурс. –

+0

Да, извините, что было не ясно, URL выше обновляет плеер с идентификатором 12, и вы передадите объект JSON на этот URL с данными, чтобы обновить позицию игроков. –

ответ

0

Я думаю, что я вижу две проблемы

  1. вы не определены достаточно ресурсов
  2. вы путаете HTTP с вашей моделью домена

Попробуйте что-то вроде этого

PUT /api/v1/matches/{match-id} 

{ winner : { id }, loser : { id }, ... } 

Поместить в API сообщение с описанием результатов игры (POST является приемлемым, PUT лучше идемпотентности).

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

Когда кто-то хочет видеть рейтинг игроков ...

GET /api/v1/leagues/{league-id}/standings 

вы посылаете их на ресурс, который возвращает представление текущего рейтинга в вашей модели.

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

GET /api/v1/leagues/{league-id}/players?orderBy=position 

Представление данных в теле запроса, отправленный вам клиент не сериализации объект в вашей модели домена, это сериализация сообщения, адресованного вашей модели домена.

+0

Делает большой смысл! По сути, это то, что я делаю, отправляя результат на сервер, который выполняет логику, необходимую для обновления таблиц лиг. Он просто не соответствовал моим ресурсам api, и ваш ответ точно подвел итог тому, что это было. Пытаясь сохранить это просто, я на самом деле делал это более сложным. Что бы вы вернули с просьбы отправить новый матч в api? Или вы оставите клиента отправить дополнительный запрос на обновление, если он захочет? –

+0

В зависимости от используемого вами метода. С PUT я бы как можно ближе подошел к спецификации HTTP: вы возвращаете представление ресурса, который был просто PUT. – VoiceOfUnreason

+0

С POST вы не так сильно ограничены, поэтому можете перенаправить на какой-то другой ресурс, не оскорбив пуристов. – VoiceOfUnreason

0

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

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

Данное предложение основано на предположении, что у вас не так много игроков в лиге (может быть> 100). В этом случае я бы предложил, чтобы подход 1 был лучше.

Таким образом, ваш URL-адрес API может быть ...

(POST)/API/v1/лиги/{лигой идентификатор}

И ваше тело запроса, может быть

"игроки": [{ "player- идентификатор ":" 101" , "newScore": "10"}, { "игрок-идентификатор": "103", "newScore": "20"} ]

Ваш ответ может быть фу список игроков в итоговой лиге.

"игроки": [ { "игрок-ID": "101", "положение": "1"}, { "игрок-ID": "102", "положение": "2 "}, {" player-id ":" 103 "," position ":" 3 "} {" player-id ":" 104 "," position ":" 4 "} {" player-id " : "105", "позиция": "5"} ]

+0

Спасибо, это то, что я делаю, так как в лиге всего около 10 игроков. Единственное осложнение - когда два игрока переключают лиги.Это происходит, когда победитель находится в зоне продвижения нижней лиги, а проигравший находится в зоне вылета. В этом случае я должен отправить данные за две лиги. –

+0

По-прежнему имеет смысл отправить обновленные лиги и изменить модель пользовательского интерфейса. Таким образом, вы можете инкапсулировать транзакцию и упростить свой код интерфейса. –

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