Java týden Java týden
Pouze tento týden sleva až 80 % na celý Java e-learning!
Brno? Vypsali jsme pro vás nové termíny školení OOP v Brně!
Avatar
Šimon Rácz
Člen
Avatar
Šimon Rácz:29.12.2018 18:43

Zdravím,

jakým způsobem se obyčejně přistupuje k poli "included" ve standardu JSON:API? Příkladový kód na stránkách https://jsonapi.org/.

Předem díky za odpovědi.

 
Odpovědět 29.12.2018 18:43
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Šimon Rácz
Jindřich Máca:29.12.2018 23:25

Zdravím,

co je myšleno tím "přistupuje"? Pokud to API tvoříš, tak postupuješ podle toho standardu, je to v něm popsáno. A pokud ho konzumuješ, tak stejně jako k ostatním datům, prostě si vezmeš, co je posláno samozřejmě za předpokladu, že to k něčemu potřebuješ. Můžeš tu otázku případně zkusit formulovat trochu lépe? Díky!

 
Nahoru Odpovědět  +1 29.12.2018 23:25
Avatar
Šimon Rácz
Člen
Avatar
Odpovídá na Jindřich Máca
Šimon Rácz:29.12.2018 23:58

Ahoj, díky za odpověď. Ano, jedná se o konzumaci vlastního API. Příklad: z API dostanu v JSON kolekci článků, to je tedy položka "data". Každý článek má autora. To by byla položka "data"->"relationships" a "included". Kdybych chtěl vypsat všechny články s autorem, projel bych nejspíš položku "data", kde jsou všechny články, jenže v "data"->"relationships" jsou jen IDčka. Pro bližší informace, např. jméno, musím jít do included. Included je jen pole s číselným indexem, čili mě nenapadá žádná rozumná možnost, jak k němu přistupovat z toho foreach. (Maximálně udělat další foreach a kontrolovat, jestli se shoduje ID, jenže to mi performance-wise přijde jako blbost.)

(Přikládám ilustrační kód, psal jsem narychlo, tak je nejspíš plný chyb, jde ale jen o ilustraci.)

{
        "data": [{
                        "type": "articles",
                        "id": "1",
                        "attributes": "",
                        "relationships": [{
                                "type": "users",
                                "id": "1"
                        }]
                },
                {
                        "type": "articles",
                        "id": "2",
                        "attributes": "",
                        "relationships": [{
                                "type": "users",
                                "id": "1"
                        }]
                },
                {
                        "type": "articles",
                        "id": "3",
                        "attributes": "",
                        "relationships": [{
                                "type": "users",
                                "id": "2"
                        }]
                }
        ],
        "included": [{
                        "type": "users",
                        "id": "1",
                        "name": "John"
                },
                {
                        "type": "users",
                        "id": "2",
                        "name": "Patrick"
                }
        ]
}
 
Nahoru Odpovědět  +1 29.12.2018 23:58
Avatar
Odpovídá na Šimon Rácz
Vladislav Ladicky:30.12.2018 1:14

Bez toho precyklenia poľa included to ale nepôjde. Zato však stačí urobiť to raz. Mám na mysli napríklad urobiť si nové pole, kde index bude zhodný s id užívateľa.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět  +1 30.12.2018 1:14
Avatar
Matúš Petrofčík
Šéfredaktor
Avatar
Odpovídá na Šimon Rácz
Matúš Petrofčík:30.12.2018 1:26

Tak ako píše Vladislav, bez ďalšieho foreach to asi nepôjde.

Pozor na to, že musíš kontrolovať aj type nie len rovnaké id. V poli included môže byť viacero typov (všetko čo je v data.relationships).

Viz ukážku (odstránil som z nej links):

{
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON:API paints my bikeshed!"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "9" }
      },
      "comments": {
        "data": [
          { "type": "comments", "id": "5" },
          { "type": "comments", "id": "12" }
        ]
      }
    }
  }],
  "included": [{
    "type": "people",
    "id": "9",
    "attributes": {
      "firstName": "Dan",
      "lastName": "Gebhardt",
      "twitter": "dgeb"
    }
  }, {
    "type": "comments",
    "id": "5",
    "attributes": {
      "body": "First!"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "2" }
      }
    }
  }, {
    "type": "comments",
    "id": "12",
    "attributes": {
      "body": "I like XML better"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "9" }
      }
    }
  }]
}
Nahoru Odpovědět  +1 30.12.2018 1:26
obsah kocky = r^2 ... a preto vlak drnká
Avatar
Matúš Petrofčík
Šéfredaktor
Avatar
Odpovídá na Šimon Rácz
Matúš Petrofčík:30.12.2018 1:28

Neexistuje nejaký balíček, ktorý ti tie dáta z API namapuje na nejaké použiteľné objekty, aby si to nemusel riešiť sám? Imho to už niekto vymyslel :)

Nahoru Odpovědět  +1 30.12.2018 1:28
obsah kocky = r^2 ... a preto vlak drnká
Avatar
Šimon Rácz
Člen
Avatar
Odpovídá na Matúš Petrofčík
Šimon Rácz:30.12.2018 1:31

Vidíš, to mě nenapadlo. Zdá se, že nějaké parsery existují. Děkuji všem za odpovědi.

 
Nahoru Odpovědět 30.12.2018 1:31
Avatar
Matúš Petrofčík
Šéfredaktor
Avatar
Odpovídá na Šimon Rácz
Matúš Petrofčík:30.12.2018 1:32

Nz ;) Daj potom vedieť ako si dopadol.

Nahoru Odpovědět 30.12.2018 1:32
obsah kocky = r^2 ... a preto vlak drnká
Avatar
Šimon Rácz
Člen
Avatar
Šimon Rácz:30.12.2018 1:33

Kdyby někoho zajímalo, našel jsem teď narychlo třeba tento: https://github.com/…-serializer/

 
Nahoru Odpovědět 30.12.2018 1:33
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Šimon Rácz
Jindřich Máca:30.12.2018 1:36

Přesně jak radí Vladislav Ladicky, udělej si z toho "included" nové pole s indexy podle ID uživatelů. Je to poměrně jednoduché. Předpokládejme, že máš např. ta vzorová data, co jsi sem posílal, uložena v proměnné response. Potom kód v JavaScriptu (ES6) může vypadat třeba takto:

const response = {...}; // Vzorová data.
const users = response.included.reduce((accumulator, user) => {
        if (user.type === 'users' && user.id) accumulator[user.id] = user;
        return accumulator;
}, {});

Teď už máš přímo to pole users, se kterým se bude lépe pracovat podle toho ID:

console.log(users[2]); // ID 2 => {type: "users", id: "2", name: "Patrick"}
 
Nahoru Odpovědět  +2 30.12.2018 1:36
Avatar
Odpovídá na Šimon Rácz
Vladislav Ladicky:30.12.2018 1:48

Jéje, dík za akceptovanie :) A ešte poznámka ... ak máš takýchto vzťahov viacero, bolo by možno vhodné prejsť z REST na GraphQL API. Mapovať si takéto veci na frontende, aspoň pričasto teda, je zhovadilosť. S GraphQL sa ti to vráti tak, ako potrebuješ. Napríklad miesto nič nehovoriaceho ID sa ti v relationship môže vrátiť rovno príslušné NAME a TYPE.

 
Nahoru Odpovědět  +1 30.12.2018 1:48
Avatar
Šimon Rácz
Člen
Avatar
Odpovídá na Vladislav Ladicky
Šimon Rácz:30.12.2018 2:09

To zní zajímavě, děkuji za tip. Určitě se na to podívám

 
Nahoru Odpovědět 30.12.2018 2:09
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 12 zpráv z 12.