Для манипулирования состоянием ресурсов мне часто нравится использовать «ведра состояния». Идея состоит в том, что когда вы «добавляете» объект в этот сегмент, он получает этот статус. Это все равно что иметь входящие и исходящие коробки на столе. Местоположение документа определяет его статус.
Итак, вы можете сделать что-то простое, например:
POST /Expenses/Approved
{ .. Expense document ... }
или для более сложного случая, на который вы намекали в документе, когда несколько человек должны утвердить документ.
POST /ExpenseApprover/John/ApprovedExpenses
{ .. Expense document ... }
Если вам нужно представить отчет о расходах на утверждение, вы можете сделать
POST /ExpenseApprover/John/Pending
{ .. Expense document ... }
И не забывайте, что гипермедиа может включить этот рабочий процесс. Представьте, что кто-то создает первоначальный отчет о расходах, сервер может ответить следующим JSON.
{ "id" : "234",
"title": "Trip to NY", "totalcost": "400 USD",
"submit_url": "/ExpenseApprover/John/Pending"
}
Клиент может отправить POST в submit_url, чтобы перевести расходы на следующий шаг. Затем, когда Джон получает счет, он получает
{ "id" : "234",
"title": "Trip to NY", "totalcost": "400 USD",
"approve_url": "/ExpenseApprover/Finance/Pending",
"denied_url": "/ExpenseApprover/John/Denied",
}
Когда финансовый отдел делает
GET /ExpenseApprover/Finance/Pending
они могут получить список ожидающих расходов,
{ PendingExpense: [
{ "id" : "234",
"title": "Trip to NY", "totalcost": "400 USD",
"approve_url": "/Expense/Approved",
"denied_url": "/ExpenseApprover/Finance/Denied",
}
]
}
Простите мой ужасный JSON, но я надеюсь, что вы поймете, что, включив ссылку в ответ, вы сможете управлять ходом вашего приложения. Вы также можете перестать беспокоиться о том, как выглядит URL, потому что клиенту на самом деле все равно. Клиент читает URL-адрес из ответа на основе имени свойства и разыменовывает его. Вы можете миллион раз передумать о том, какова лучшая структура URL, и ваши клиенты не пострадают. Только не меняйте название недвижимости!
Эти URL-адреса «корзины состояния» используются для хранения набора ресурсов, имеющих аналогичный статус. Идея в том, что вы поместите документ в коллекцию:
POST /ExpenseApprover/Finance/Denied
{"id" : "234", "title": "Trip to NY", "totalcost": "400 USD"}
Нет необходимости однозначно определять конкретные расходы, которые вы добавляете в URL, потому что основной документ должен содержать какое-то значение идентифицирующего ключа.
Этот метод также подходит для обозначения расходов, имеющих расхождения. Вы просто создаете новый ресурс, содержащий расходы с расхождениями, и публикуете в нем свой отчет о расходах.
POST /Discrepancies
{"id" : "234", "title": "Trip to NY", "totalcost": "400 USD"}