Come esporre i vincoli di campo usando HATEOAS?

5

Ad esempio abbiamo entità object :

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

Come può l'API esprimere tramite HATEOAS che il campo status può avere solo i valori new e completed (ma non per esempio canceled )?

    
posta mikhail 28.09.2018 - 12:59
fonte

4 risposte

0

In genere, lo fai in due modi

Nel mondo dell'HTML, le operazioni non sicure sono state descritte dai moduli e la descrizione del modulo potrebbe includere suggerimenti per il client su quali possibili valori erano previsti.

In un mondo in cui stai manipolando le rappresentazioni delle risorse direttamente, questo è normalmente ottenuto documentando uno schema per la rappresentazione e all'interno di quello schema che documenta le restrizioni sulle informazioni contenute all'interno.

Ad esempio, la specifica Patch JSON documenta ciò che operazioni sono supportate. Attaccare qualsiasi altra cosa significa che non stai fornendo un documento application/json-patch+json valido.

Ma se sto leggendo il tuo esempio correttamente, quello che stai cercando di fare è permettere al client di guidare alcune risorse allo stato successivo di un FSM. Per quanto posso dire, nessuno sta sostenendo che è una buona misura per il 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 allo stesso modo PATCH ) si adattano bene all'authoring remoto: situazioni in cui il client è l'autorità per le informazioni e invia semplicemente al server una copia memorizzabile nella cache. Non è adatto per manipolare le risorse in cui il server, piuttosto che il client, è la fonte della verità.

    
risposta data 28.09.2018 - 15:57
fonte
4

JSON Hyper-Schema è ottimo per questo genere di cose. Permette di definire uno schema JSON per il JSON che ci si aspetta dalla richiesta.

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"] }
        }
      }
    }
  ]
}

Questo indica a un agente utente che è possibile edit (predefinito su PUT ) questa risorsa e la risorsa deve essere conforme al dato schema che è lo schema della risorsa con un vincolo extra.

    
risposta data 15.11.2018 - 05:16
fonte
1

HATEOAS è solo un acronimo per "mettere link e moduli nella tua risposta".

Il formato di risposta (non REST o HATEOAS) determina come sono espressi e il grado in cui una risorsa può specificare i vincoli di qualsiasi valore generato dall'utente per i collegamenti basati su modelli.

L'opzione migliore è trovare o inventare un formato di risposta che contenga le leve necessarie per poter specificare i tuoi vincoli nel grado richiesto.

È molto improbabile che esista un formato che sia in grado di specificare tutto perfettamente, ad esempio, in HTML, un modulo di ricerca con due input non può specificare che la lunghezza combinata dell'URL risultante sia inferiore a qualsiasi lunghezza massima tua il server può gestire (ad esempio 4096 byte). E arricciare è comunque in grado di generare qualsiasi input, quindi la tua risorsa deve essere in grado di identificare e rifiutare input non validi.

    
risposta data 02.10.2018 - 11:20
fonte
1

Non vorrei reinventare la ruota e darei un'occhiata ad alcune delle implementazioni di HATEOAS là fuori, come ad esempio, HAL di Mike Kelly.

HAL introduce qualcosa chiamato CURIEs attraverso il quale possiamo etichettare link e contenuti. Queste etichette sono legate a una documentazione del modello API, che è anche rilevabile dai client poiché sono rappresentati come collegamenti nel modello a oggetti.

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

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

Dove portano questi link è un altro argomento. Potrebbero condurci a file JSON statici dove scriviamo i nostri schemi, o come ho implementato una volta, potrebbero collegare gli endpoint di Swagger. Il modello di documento di Swagger è basato su OpenAPI che è stato testato in battaglia abbastanza per la comunità per me di adottarlo.

Entrambi, HAL e Swagger (OpenAPI) hanno diversi strumenti e librerie (per tecnologie diverse) per farti dimenticare di reinventare la ruota (di nuovo) sul lato client.

    
risposta data 15.11.2018 - 10:08
fonte

Leggi altre domande sui tag