Como expor restrições de campo usando HATEOAS?

5

Por exemplo, temos entidade object :

{
    "id": 10,
    "name": "First object",
    "status": "new",
    "manager_id": 200,
    "links": [
        {
            "href": "self",
            "type" : "PUT",
        }
    ]
}

Como a API pode expressar por meio do HATEOAS que o campo status pode ter apenas os valores new e completed (mas não, por exemplo, canceled )?

    
por mikhail 28.09.2018 / 12:59
fonte

4 respostas

0

Normalmente, você faz isso de duas maneiras

No mundo do HTML, as operações inseguras foram descritas por formulários, e a descrição do formulário pode incluir dicas para o cliente sobre os possíveis valores esperados.

Em um mundo onde você está manipulando representações dos recursos diretamente, isso normalmente é obtido documentando-se um esquema para a representação e dentro desse esquema documentando as restrições sobre as informações contidas nele.

Por exemplo, a especificação JSON Patch documenta o que operações são suportadas. Furar em qualquer outra coisa significa que você não está fornecendo um documento application/json-patch+json válido.

Mas se eu estou lendo o seu exemplo corretamente, o que você está tentando fazer é permitir que o cliente direcione algum recurso para o próximo estado de um FSM. Tanto quanto eu posso dizer, ninguém está afirmando que é um bom ajuste para o verbo PUT

Clients should never decide the current state of an entity, instead, they should request transitions of that entity to the desired state. -- Richard Clayton

PUT (e semelhantemente PATCH ) são bons ajustes para autoria remota: situações em que o cliente é a autoridade para a informação e está apenas enviando para o servidor uma cópia armazenável em cache. Não é um bom ajuste para manipular recursos onde o servidor, em vez do cliente, é a fonte da verdade.

    
por 28.09.2018 / 15:57
fonte
4

O JSON Hyper-Schema é ótimo para esse tipo de coisa. Ele permite que você defina um esquema JSON para o JSON que você espera da solicitação.

GET /my-resource/10

HTTP/1.1 200 OK
Content-Type: application/json
Link: </schema/my-resource>; rel="describedby"

{
  "id": 10,
  "name": "First object",
  "status": "new",
  "manager_id": 200
}

GET /schema/my-resource

HTTP/1.1 200 OK
Content-Type: application/schema+json

{
  "$schema": "http://json-schema.org/draft-04/hyper-schema#",
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "name": { "type": "string" },
    "status": { "enum": ["new", "completed", "canceled"] },
    "manager_id": { "type": "integer" }
  },
  "links": [
    { "rel": "self", "href": "/my-resource/{id}" },
    {
      "rel": "edit",
      "href": "/my-resource/{id}",
      "schema": {
        "allOf": [{ "$ref": "#" }],
        "properties": {
          "status": { "enum": ["new", "completed"] }
        }
      }
    }
  ]
}

Isso informa ao agente do usuário que você pode usar edit (o padrão é PUT ) e o recurso deve estar de acordo com o schema , que é o esquema do recurso com uma restrição extra.

    
por 15.11.2018 / 05:16
fonte
1

HATEOAS é apenas um acrônimo ruim para "colocar links e formulários em sua resposta".

O formato de resposta (não REST ou HATEOAS) determina como eles são expressos e o grau em que um recurso pode especificar as restrições de quaisquer valores gerados pelo usuário para links modelados.

Sua melhor opção é encontrar ou inventar um formato de resposta que contenha as alavancas necessárias para poder especificar suas restrições na medida em que você precisar.

É muito improvável que exista um formato que possa especificar tudo perfeitamente, por exemplo, em HTML, um formulário de pesquisa com duas entradas não pode especificar que o comprimento combinado do URL GET resultante seja menor do que o comprimento máximo servidor pode manipular (digamos, 4096 bytes). E o curl é capaz de gerar qualquer entrada de qualquer maneira, portanto, seu recurso precisa ser capaz de identificar e rejeitar entradas inválidas.

    
por 02.10.2018 / 11:20
fonte
1

Eu não reinventaria a roda e daria uma olhada em algumas das implementações do HATEOAS, como, por exemplo, HAL por Mike Kelly.

A HAL introduz algo chamado CURIEs através do qual podemos rotular links e conteúdo. Esses rótulos estão vinculados a uma documentação do Modelo de API, que também pode ser descoberta pelos clientes, pois eles são representados como links no modelo de objeto.

"_links": {
  "curies": [
    {
      "name": "doc",
      "href": "http://haltalk.herokuapp.com/docs/{rel}",
      "templated": true
    }
  ],

  "doc:latest-posts": {
    "href": "/posts/latest"
  }
}

Onde esses links levam a outro assunto. Eles poderiam nos levar a arquivos JSON estáticos onde nós digitamos nossos próprios esquemas, ou como eu implementei uma vez, eles poderiam estar ligando os pontos finais do Swagger. O modelo de documento de Swagger é baseado em OpenAPI que foi testado em batalha o suficiente para a comunidade para eu adotá-lo.

Ambos, HAL e Swagger (OpenAPI) têm várias ferramentas e bibliotecas (para diferentes tecnologias) para você esquecer de reinventar a roda (novamente) no lado do cliente.

    
por 15.11.2018 / 10:08
fonte