REST-full design: approccio raccomandato per il recupero delle entità correlate

5

Supponiamo di avere due entità author e post , dove ogni post ha un autore . Sono implementate queste chiamate REST

  1. Ottieni un elenco impaginato di post : GET /posts?page={page}

  2. Ottieni un elenco di autori: GET /authors

  3. Ottieni un singolo autore: GET /authors/{id}

Supponiamo che abbia anche un client che utilizza il servizio REST. Questo cliente desidera mostrare un elenco impaginato di post con autori correlati.

Ora, come funzionerebbe il servizio REST per quanto riguarda le entità correlate? Esistono i seguenti metodi:

  1. Lascia che la chiamata di GET /posts?page=1 restituisca i post e gli autori correlati in un'unica chiamata. Facoltativamente, rendi questo parametro separato, ad es. GET /posts?page=1&related=true o GET /posts/related?page=1 .

  2. Consenti al client di scorrere i post e ottenere l'autore per ogni post utilizzando la chiamata GET /author/{id} .

  3. Lascia che la chiamata REST per gli autori accetti un elenco di ID come filtro, in modo che il client possa ottenere gli autori correlati in una chiamata, ad es. GET /authors?ids=10,12,16,30,43,44,58 .

Il metodo 1 è il più semplice dal punto di vista del cliente poiché ottiene tutti i dati necessari in un'unica chiamata. Ma il servizio REST è limitato qui, non dovrebbe essere necessario installare alcun client particolare perché ogni client ha altri requisiti.

Il metodo 2 è l'approccio REST più pulito, ma diciamo che una pagina ha 30 post, il client deve effettuare 30 chiamate REST aggiuntive per recuperare gli autori correlati. Questo è molto inefficiente.

Il metodo 3 è forse migliore dei tre, poiché è un'implementazione REST relativamente pulita (rispetto al metodo 1) e richiede solo una chiamata in più per pagina.

C'è un approccio consigliato qui?

    
posta Jaap van Hengstum 17.12.2014 - 16:18
fonte

4 risposte

3

Cioè, quali link sono per:

es. richiedendo il primo post tramite OTTIENI http://example.com/posts/1

{
    "id": "1",
    "author": {
        "nickname": "me"
    },
    "links": [
        {
            "rel": "self",
            "href": "http://example.com/posts/1"
        },
        {
            "rel": "author",
            "href": "http://example.com/authors/me"
        }
    ]
}

La risposta contiene un link all'autore (denominato me ). Se vuoi recuperare tutti i post di me , dovresti fare un OTTIENI a http://example.com/posts?author=me ; e se lo vuoi impaginato, dovresti aggiungere un queryparameter come http://example.com/posts?author=me&page=1 .

Supponiamo che tu abbia collaborazioni tra vari autori, la risposta iniziale sarebbe stata:

{
    "id": "1",
    "authors": [
        {
            "nickname": "me"
        },
        {
            "nickname": "mo"
        },
        {
            "nickname": "ma"
        }
    ],
    "links": [
        {
            "rel": "self",
            "href": "http://example.com/posts/1"
        },
        {
            "rel": "author",
            "href": "http://example.com/authors/me"
        },
        {
            "rel": "author",
            "href": "http://example.com/authors/mo"
        },
        {
            "rel": "author",
            "href": "http://example.com/authors/ma"
        }
    ]
}

D'altra parte, sotto la sezione link dell'autore, dovrebbe esserci solo un riferimento all'ultimo post (per evitare che troppi dati ci siano).

Se vuoi ottenere un set di tutti i post collaborativi dal trio di cui sopra, puoi eseguire una query nel modo seguente:

OTTIENI http://example.com/posts?author=mo,me,ma

Se vuoi che tutti i messaggi, compreso quello collaborativo, provengano dal trio, devi eseguire una query in questo modo:

OTTIENI http://example.com/posts?author=mo|me|ma

Questo è un approccio pulito e diretto.

Per esprimere, che qualcosa è correlato , usi link . Se vuoi filtrare lo fai tramite querystring.

    
risposta data 17.12.2014 - 22:42
fonte
2

Potresti fare qualcosa di simile a ciò che fanno i discog nella loro API, link . Quando richiedi un rilascio / rilascio / {release_id} la risposta include anche un sottoinsieme di dati dell'artista, estratto dal corpo della risposta:

{    
    "title": "Never Gonna Give You Up",
    "id": 249504,
    "artists": [
        {
            "anv": "",
            "id": 72872,
            "join": "",
            "name": "Rick Astley",
            "resource_url": "https://api.discogs.com/artists/72872",
            "role": "",
            "tracks": ""
        }
    ]
}

Nel tuo caso, invece di artisti, potrebbe essere autore e se il cliente desidera maggiori informazioni sull'autore dovrebbe ovviamente utilizzare GET / authors / {id}.

    
risposta data 17.12.2014 - 16:53
fonte
0

Puoi anche farlo in una sola chiamata incorporando autori all'interno di post . JSON Hypertext Application Language descrive come eseguire questa operazione, vedi link

es. (copia modificata dal doc):

{
    "_links": {
        "self": { "href": "/posts" },
        "next": { "href": "/posts?page=2" },
        "find": { "href": "/posts{?id}", "templated": true }
    },
    "_embedded": {
        "post": [{
            "_links": {
                "self": { "href": "/posts/321" },
                "author": { "href": "/author/alan-watts" }
            },
            "_embedded": {
                "author": {
                    "_links": { "self": { "href": "/author/alan-watts" } },
                    "name": "Alan Watts",
                    "born": "January 6, 1915",
                    "died": "November 16, 1973"
                }
            }
            "title": "foo"
        }, {
            "_links": {
                "self": { "href": "/posts/123" },
                "author": { "href": "/author/alan-watts" }
            },
            "_embedded": {
                "author": {
                    "_links": { "self": { "href": "/author/alan-watts" } },
                    "name": "Alan Watts",
                    "born": "January 6, 1915",
                    "died": "November 16, 1973"
                }
            },
            "title": "bar"
        }]
    }
}
    
risposta data 18.12.2014 - 02:49
fonte
0

Potresti trarre ispirazione dal protocollo ODATA come variante dell'opzione 1. Ha le cosiddette opzioni di query una delle quali è $ expand che prende il valore della risorsa correlata da restituire.

L'opzione di query $ expand system specifica le risorse correlate da includere in linea con le risorse recuperate. La richiesta di seguito restituisce le persone con proprietà di navigazione Post di un autore.

GET / authors / {id} / $ expand = Post

link

Puoi crearne uno proprio chiamato $ related.

    
risposta data 18.12.2014 - 06:04
fonte

Leggi altre domande sui tag