Связывание действий в REST, которое создаст ресурс на основе существующего ресурса

#rest #hateoas

#rest #hateoas

Вопрос:

Я изо всех сил пытаюсь получить ссылки на действия в свой ресурс для выполнения HATEOAS.

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

Мой текущий поток (упрощенный для наглядности) для этого не использует гипермедиа для связывания действия с фактической постановкой в очередь test_request (создание ресурса задания в коллекции заданий).

Создайте ресурс test_request

 POST http://example.org/api/v1/test_request

{
    'name': 'Some example tests',
    'test': 'test1'
}


201, CREATED

{
    'id': 3
    'name': 'Some example tests',
    'test': 'test1',
    'links': [
        {
            'rel': 'self',
            'href': 'http://example.org/api/v1/test_request/3',
            'method': 'GET',
        },
        {
            'rel': 'remove',
            'href': 'http://example.org/api/v1/test_request/3',
            'method': 'DELETE',
        }]
}
 

Создайте ресурс задания

 POST http://example.org/api/v1/jobs

{
    'type': 'test_request',
    'id': 3
}


201, CREATED

{
    'id': 12,
    'type': 'test_request',
    'status': 'new',
    'links': [
        {
            'rel': 'self',
            'href': 'http://example.org/api/v1/jobs/12',
            'method': 'GET',
        },
        {
            'rel': 'remove',
            'href': 'http://example.org/api/v1/jobs/12',
            'method': 'DELETE',
        }]
}
 

Чтобы выполнить критерии гипермедиа в моем REST API, мне очень хочется добавить ссылку на действие на test_request ресурс, чтобы для него был создан новый ресурс задания.

Измененное представление test_request

 {
    'id': 3
    'name': 'Some example tests',
    'test': 'test1',
    'links': [
        {
            'rel': 'self',
            'href': 'http://example.org/api/v1/test_request/3',
            'method': 'GET',
        },
        {
            'rel': 'remove',
            'href': 'http://example.org/api/v1/test_request/3',
            'method': 'DELETE',
        },
        {
            'rel': 'http://example.org/rels/queue',
            'href': 'http://example.org/api/v1/test_request/3/queue',
            'method': 'PUT',
        }]
}
 

Итак, первые примеры (надеюсь) RESTful были моим вторым подходом с действием очереди, возможно, более беспокойным. Тем не менее, действительно приятно иметь ссылку в test_request представлении, в которой четко указано действие для выполнения следующего перехода.

Какова наилучшая практика здесь?

Ответ №1:

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

Корневой вопрос — это вопрос домена, на который действительно можете ответить только вы. Может и должен ли тест существовать, не являясь частью задания? Вам нужно продумать варианты использования и принять решение. Если тест является слабым объектом, тогда вы должны разрешить создание только через задания.

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

 POST http://example.org/api/v1/jobs

{
    'type': 'test_request',
    'links': [
       {
         rel : "test",
         href : "http://example.org/api/v1/test_request/3",
       },
       {
         rel : "test",
         href : "http://example.org/api/v1/test_request/4",
       }
     ]
}
 

Примечание: я не уверен, как ваш гипертекстовый формат работает с несколькими ссылками для одного и того же отношения … я сделал предположение.

Я считаю, что первичные ключи и внешние ключи никогда не должны существовать в RESTful API. Ссылки должны использоваться всегда.