Ресурс имеет один идентифицирующий URL (если хотите, собственный URL). Это никогда не должно измениться. Это также означает, что если вы рискуете изменить этот идентификатор в какой-то момент, тогда этот идентификатор не тот, который вы используете в URL. Если вы рискуете переработать идентификатор, то вам определенно не следует использовать этот идентификатор.
Это также означает, что у вас никогда не будет двух URL, которые однозначно идентифицируют один и тот же ресурс.
Теперь это не значит, что вы не можете получить доступ к одному и тому же ресурсу с двух разных URL. Есть много причин, почему вы хотели бы сделать это. Есть только несколько вещей, в которых вы должны убедиться.
Вы должны сделать это очень легко понятным для любого, кто использует ваш API, что происходит. Опции, которые вы перечислили, не делают этого.
Это в основном сводится к моделированию и проверке того, чтобы ваша внутренняя модель не попадала в общедоступные API. Тот факт, что у вас может быть перегруженный метод, который может принимать либо идентификатор, либо дату в качестве входного параметра, не означает, что вы должны выставить эту перегрузку.
Итак, спросите себя, какой сценарий решает каждая из двух ситуаций, и тогда это может стать очевидным.
Мне тоже не нравится предложение Стива. Как потребитель узнает, что вы можете написать «дату» вместо идентификатора, а затем внезапный доступ по дате? Это не интуитивно понятно.
Так что спросите себя, имеет ли первостепенное значение возможность использовать дату в качестве части URL-адреса или лучше добавить ее в качестве фильтра строки запроса в коллекции. Таким образом, вы можете использовать фильтр даты и времени, который может быть еще более ценным, а также более интуитивным.
В качестве альтернативы рассмотрите что-то вроде:
/years
, который может предоставить список объектов года
{
"year": 2015,
"entities": "https://api.myapp.com/years/2015/entities",
"months": [
{
"month": 1,
"name": "January",
"entities": "https://api.myapp.com/years/2015/months/1/entities",
"self": "https://api.myapp.com/years/2015/months/1"
},
... array of month objects
],
"self": "https://api.myapp.com/years/2015"
}
/years/2015/months/1
является одним примером объекта месяца
{
"month": 1,
"name": "January",
"entities": "https://api.myapp.com/years/2015/months/1/entities",
"self": "https://api.myapp.com/years/2015/months/1"
}
Свойство entity имеет ссылку на коллекцию объектов, отфильтрованных по дате.
Но, опять же, все зависит от вашей конкретной проблемы. Просто не забудьте сделать интерфейс интуитивно понятным, и не позволяйте вашему внутреннему моделированию влить в ваш публичный API. Но это совсем не простая задача.