title |
---|
Fyrirlestur 10.3 — GraphQL |
Ólafur Sverrir Kjartansson, osk@hi.is
- GraphQL er Query mál þróað hjá Facebook kringum 2012
- Núna þróað áfram af GraphQL foundation
- Að vissu leiti svar við hversu erfitt það getur verið að sækja nákvæmlega þau gögn sem við þurfum með REST
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.
- Með REST þurfum við mörg request til að nálgast margar auðlindir (resources)
- Með GraphQL getum við sótt margar auðlindir í einu request
- GraphQL byggir á týpum og reitum (types & fields), ekki endapunktum
- Server skilgreinir nákvæmlega hvaða gögn eru í boði, hvert form þeirra er, og af hvaða týpu
- Client útbýr GraphQL fyrirspurn sem velur týpur og reiti undir þeim
- Sendum query (og breytur) á slóð GraphQL servers með
GET
eðaPOST
(fer eftir uppsetningu) - Fáum til baka gögn á JSON formi sem passa við fyrirspurn
query HeroNameAndFriends {
hero {
name
friends {
name
}
}
}
Öll dæmi á graphql.org (og verkefni 6) nota GraphQL útgáfu af SWAPI—Star Wars Api.
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{ "name": "Luke Skywalker" },
{ "name": "Han Solo" },
{ "name": "Leia Organa" }
]
}
}
}
- Query getur sótt gögn sem skilgreind eru á rót (e. root) GraphQL servers
- Þessi gögn eru í langflestum tilfellum annað hvort listar eða stök (sem við sækjum eftir ID)
- Ef við erum að sækja sömu gögnin oft í mismunandi samhengi, þá getum við útbúið fragment
- Fragment skilgreinir hvaða fields á type við viljum velja
fragment char on Character {
name
appearsIn
friends {
name
}
}
query heroAndFriends {
hero {
...char
friends {
...char
}
}
}
{
"data": {
"hero": {
"name": "R2-D2",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{ "name": "..." }
]
}
}
}
- Query geta átt sér argument, bæði sem verður að senda inn (merkt með
!
) eða ekki- Annað hvort scalar type eða skilgreind type í schema (sjá að neðan)
- Sendum gildi á query arguments sem variables með query, á JSON formi
- Reitir (e. fields) geta líka tekið við arguments
query luke {
human(id: "1000") {
name
height(unit: FOOT)
}
}
"data": {
"human": {
"name": "Luke Skywalker",
"height": 5.6430448
}
}
}
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
Variables:
{
"episode": "JEDI"
}
Result:
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{ "name": "Luke Skywalker" },
{ "name": "Han Solo" },
{ "name": "Leia Organa" }
]
}
}
}
- Gögnum sem er skilað geta verið interface eða union type, þ.a. mismunandi reitir eru í boði
- Getum notað inline fragment til að velja reiti útfrá hverju er skilað
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name
... on Droid {
primaryFunction
}
... on Human {
height
}
}
}
Variables:
{ "ep": "EMPIRE" }
Result:
{
"data": {
"hero": {
"name": "Luke Skywalker",
"height": 1.72
}
}
}
- Við getum skoðað með introspection hvað er í boði á GraphQL server
- Mest notað er e.t.v.
__typename
sem er í boði á öllum fields- Gefur okkur nafn á type sem er skilað
{
search(text: "an") {
__typename
... on Human {
name
}
... on Droid {
name
}
... on Starship {
name
}
}
}
Result:
{
"data": {
"search": [
{ "__typename": "Human",
"name": "Han Solo" },
{ "__typename": "Human",
"name": "Leia Organa" },
{ "__typename": "Starship",
"name": "TIE Advanced x1" }
]
}
}
- Ef við viljum ekki bara sækja gögn heldur líka breyta þeim, þá notum við mutation
- Búum til
mutation
, ekkiquery
og tilgreinum argument - Sendum inn gögn sem JSON og fáum til baka það sem við veljum
- Nánar í skjölun
- GraphQL skilgreinir í schema hvaða týpur og reitir eru í boði
- Getum búið til okkar eigin týpur sem vísa í aðrar týpur, enda alltaf á scalar týpum fyrir gögn
Int
, signed 32 bitaFloat
, signed double-precisionString
, UTF-8Boolean
,true
eðafalse
ID
, eins og string, en ekki ætlað að vera human-readable
- Ef við ætlum að útfæra okkar eigin GraphQL þjón þurfum við að hugsa gögnin okkar sem graf
- Node.js pakkar sem er mælt með eru
express-graphql
eðaapollo-server
- GraphiQL er GraphQL IDE þar sem við getum skoðað allt schema, týpur og fields
- Mjög oft sett upp meðfram GraphQL þjóni
- Sett upp fyrir SWAPI GraphQL
- Þegar við erum að vinna með lista af gögnum skilgreinir GraphQL best practices fyrir pagination
- Notar cursor-based pagination, fáum vísun í stak og biðjum um stök fyrir eða eftir því
- Skilgreinir
pageInfo
týpu sem segir til um stöðu á pagination