PHP Academy · Oppitunti

Skeeman rakentaminen graphql-php:llä

Määritelkää tyypit ja skeema webonyx/graphql-php:llä.

Oppitunti 2/413 vaihetta

Skeeman rakentaminen graphql-php:llä on ilmainen PHP Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu PHP Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. PHP Academy-kurssilla on yhteensä 4 oppituntia.

graphql-php: viitetoteutus

webonyx/graphql-php on GraphQL:n viitetoteutuksen de facto -PHP-porttaus. Se tarjoaa tyyppijärjestelmän, jäsentimen, validoijan ja suorittajan. Määrittelette skeeman joko ohjelmallisesti (PHP-objekteina) tai SDL:stä (skeema ensin -mallilla). Tässä oppitunnissa rakennamme skeeman käsin, jotta ymmärrätte tarkasti, mitä kukin osa tekee.

composer require webonyx/graphql-php

Skalaarit ja tyyppirekisteri

Jokainen GraphQL-arvo palautuu viime kädessä skalaariksi: Int, Float, String, Boolean, ID. graphql-php:ssä nämä sijaitsevat Type-fasadissa. Koska objektityypit viittaavat toisiinsa ja itseensä, yleinen käytäntö on staattinen TypeRegistry, joka välimuistittaa jokaisen tyypin, jotta se rakennetaan vain kerran.

<?php
use GraphQL\Type\Definition\Type;

// Built-in scalars, returned as singletons:
var_dump(Type::int()->name);     // "Int"
var_dump(Type::string()->name);  // "String"
var_dump(Type::id()->name);      // "ID"
var_dump(Type::nonNull(Type::string())->toString()); // "String!"

ObjectTypen määrittäminen

ObjectType-tyypillä on name ja fields-kartta. Jokainen kenttä määrittää type-arvonsa ja voi valinnaisesti sisältää resolve-kutsun. Jos jätätte resolve-arvon pois, graphql-php käyttää oletusresolveria, joka lukee vastaavan taulukkoavaimen tai propertyn/getterin vanhemman arvosta.

<?php
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

$postType = new ObjectType([
    'name' => 'Post',
    'fields' => [
        'id'    => Type::nonNull(Type::id()),
        'title' => Type::nonNull(Type::string()),
        'body'  => Type::string(),
    ],
]);

Non-Null- ja listatyypit

Paketointityypit ilmaisevat null-arvojen sallittavuuden ja kardinaliteetin:

  • Type::nonNull(T) → T! (ei koskaan null).
  • Type::listOf(T) → [T] (lista, joka voi olla null ja jonka jäsenet voivat olla null).
  • [Post!]! = ei-null-arvoinen lista ei-null-arvoisista Post-olioista → nonNull(listOf(nonNull($postType))).

Määritelkää tämä oikein: kyse on skeemanne null-sopimuksesta asiakkaiden kanssa.

<?php
use GraphQL\Type\Definition\Type;

// [Post!]!  -- a required list whose elements are never null
$wrapped = Type::nonNull(Type::listOf(Type::nonNull(Type::string())));
echo $wrapped->toString(), "\n"; // [String!]!

Laiskat kentät ratkaisevat kehäviittaukset

User-tyypillä on posts ja Post-tyypillä author (User). Toisiinsa viittaavat tyypit rakennetaan välittämällä fields sulkeumana taulukon sijaan. Sulkeuma suoritetaan laiskasti vasta, kun molemmat tyypit ovat olemassa, mikä ratkaisee muna ja kana -ongelman.

<?php
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

class Types {
    private static array $cache = [];

    public static function user(): ObjectType {
        return self::$cache['User'] ??= new ObjectType([
            'name' => 'User',
            'fields' => fn() => [           // lazy!
                'id'    => Type::nonNull(Type::id()),
                'name'  => Type::nonNull(Type::string()),
                'posts' => Type::listOf(self::post()),
            ],
        ]);
    }

    public static function post(): ObjectType {
        return self::$cache['Post'] ??= new ObjectType([
            'name' => 'Post',
            'fields' => fn() => [
                'id'     => Type::nonNull(Type::id()),
                'title'  => Type::nonNull(Type::string()),
                'author' => self::user(),    // back-reference
            ],
        ]);
    }
}

Kenttäargumentit

Kentät voivat ottaa argumentteja. Määritelkää ne args-avaimen alle; ne saapuvat resolverin toisena parametrina ($args). Myös argumentit ovat tyypitettyjä, ne voivat olla ei-null-arvoisia ja niille voidaan antaa defaultValue.

<?php
use GraphQL\Type\Definition\Type;

$userField = [
    'type' => Type::string(),
    'args' => [
        'id'     => Type::nonNull(Type::id()),
        'locale' => ['type' => Type::string(), 'defaultValue' => 'en'],
    ],
    'resolve' => fn($root, array $args) => "user {$args['id']} ({$args['locale']})",
];

Juuren Query-tyyppi

Jokainen skeema tarvitsee juurityypin Query — aloituspisteet, joista asiakkaat voivat käynnistää kyselyitä. Tässä tuomme näkyviin yhden hello-kentän, jotta voimme suorittaa kyselyn alusta loppuun. Juuriresolverin ensimmäinen argumentti on skeeman rootValue (usein null).

<?php
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'hello' => [
            'type' => Type::string(),
            'args' => ['name' => Type::nonNull(Type::string())],
            'resolve' => fn($root, array $args) => 'Hello, ' . $args['name'],
        ],
    ],
]);

Skeeman kokoaminen ja suorittaminen

Käärikää kyselytyyppi Schema-tyypin sisään ja suorittakaa kyselymerkkijono kutsulla GraphQL::executeQuery(). Tulosolio muunnetaan kanoniseksi { data, errors }-taulukoksi kutsulla toArray().

<?php
require 'vendor/autoload.php';

use GraphQL\GraphQL;
use GraphQL\Type\Schema;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'hello' => [
            'type' => Type::string(),
            'args' => ['name' => Type::nonNull(Type::string())],
            'resolve' => fn($root, $args) => 'Hello, ' . $args['name'],
        ],
    ],
]);

$schema = new Schema(['query' => $queryType]);
$result = GraphQL::executeQuery($schema, '{ hello(name: "Ada") }');
echo json_encode($result->toArray());
// {"data":{"hello":"Hello, Ada"}}

Skeema ensin -vaihtoehto BuildScheman avulla

Jos suositte SDL:ää, BuildSchema::build() jäsentää skeemamerkkijonon suoritettavaksi skeemaksi. Liitätte resolverit sen jälkeen erikseen (esimerkiksi kenttäresolverin callbackilla), jolloin tyyppimääritykset pysyvät deklaratiivisina ja logiikka PHP:ssä.

<?php
use GraphQL\Utils\BuildSchema;

$sdl = <<<'GQL'
type Query {
  hello(name: String!): String
}
GQL;

$schema = BuildSchema::build($sdl);
// Provide resolvers via the executeQuery $fieldResolver argument
// or with a type config decorator.

Validoikaa ennen julkaisua

graphql-php validoi saapuvat kyselyt skeemaa vasten automaattisesti ennen suoritusta. Voitte myös varmistaa skeeman sisäisen eheyden rakennusvaiheessa tai CI:ssä kutsulla $schema->assertValid() — näin löydätte kirjoitusvirheet ja rikkinäiset viittaukset ennen käyttöönottoa, ette vasta pyynnön aikana.

<?php
use GraphQL\Type\Schema;

/** @var Schema $schema */
$schema->assertValid(); // throws InvariantViolation on a broken schema
echo "schema OK\n";

Enumeraatiot ja mukautetut skalaarit

Objektien lisäksi useimmat skeemat täydentyvät kahdella muulla kohdetyypillä. EnumType rajoittaa kentän kiinteään joukkoon nimettyjä arvoja. CustomScalarType mahdollistaa toimialakohtaisten skalaarien (DateTime, Email) määrittämisen omalla serialize/parseValue/parseLiteral-logiikallanne, jotta arvot validoidaan ja normalisoidaan rajapinnalla.

<?php
use GraphQL\Type\Definition\EnumType;

$statusEnum = new EnumType([
    'name' => 'PostStatus',
    'values' => [
        'DRAFT'     => ['value' => 0],
        'PUBLISHED' => ['value' => 1],
        'ARCHIVED'  => ['value' => 2],
    ],
]);
// A field typed as $statusEnum only accepts DRAFT/PUBLISHED/ARCHIVED.

Pikatarkistus

Miksi fields kannattaa välittää sulkeumana?

Kertaus

Rakensitte skeeman alusta alkaen:

  • Skalaarit ja paketointityypit (nonNull, listOf) ilmaisevat null-arvojen ja kardinaliteetin sopimuksen.
  • ObjectType kenttäkarttoineen tai laiskine sulkeumineen määrittää rakenteenne.
  • Välimuistittava tyyppirekisteri käsittelee kehäviittaukset.
  • Kentät ottavat tyypitettyjä args-argumentteja; juuren Query-tyyppi on aloituspiste.
  • GraphQL::executeQuery() suorittaa kyselyn; assertValid() varmistaa skeeman kelvollisuuden CI:ssä.

Seuraavaksi käsitellään resolvereita, mutaatioita ja tilauksia.

Aloita maksutta

Opi PHP tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
49
Oppitunnit
195

Usein kysytyt kysymykset

Onko oppitunti ”Skeeman rakentaminen graphql-php:llä” ilmainen?

Kyllä – oppitunnin ”Skeeman rakentaminen graphql-php:llä” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko PHP Academy-kurssin, päivitä CoddyKit PROhon. PHP Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Skeeman rakentaminen graphql-php:llä”?

Määritelkää tyypit ja skeema webonyx/graphql-php:llä. Harjoittelet PHP Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni PHP Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin PHP Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Skeeman rakentaminen graphql-php:llä”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä PHP Academy-oppitunnilla?

Kyllä. Jokainen PHP Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. GraphQL vastaan REST
  2. Skeeman rakentaminen graphql-php:llä
  3. Resolverit, mutaatiot ja tilaukset
  4. Suorituskyky: N+1 ja DataLoader
← Takaisin: PHP Academy