Gatsby + Drupal: Custom GraphQL schema

Een developer (moi) koppelt Gatsby aan Drupal. Drupal zegt "Ik heb een gerelateerd content veld waar je 7 verschillende entity-types aan kunt refereren, maar maximaal 3 waarden zijn toegestaan". Developer zegt "Dat is prima". Gatsby zegt "Je moet wel zorgen dat die 7 types in die 3 velden zitten". Badumtss. Tot zover het 'mopje'.

Het probleem met Gatsby en Drupal is vrij eenvoudig dit: als een veld geen waarde heeft in de Drupal, kan Gatsby deze niet meenemen in zijn query. Is het veld in geen enkele entity gevuld, dan komt het veld in het geheel niet mee. Het veld komt dan niet terug uit de query, maar dat is vrij lastig als je iets in je frontend wilt implementeren voor het geval dat het veld wel gevuld is.

Een voorbeeld:

Bij een project heb een paragraaf type met wat optionele velden, zoals een lijst voor achtergrondkleuren, marges, etc. Sommige van die velden bestaan "voor het geval dat" maar zijn (tijdens de bouw) niet gevuld. Dit heeft als gevolg dat deze velden niet meekomen in het schema wat Gatsby automatisch opstelt en zodoende kan ik die velden ook niet meenemen in de query met als gevolg een foutmelding (Cannot query field "[fieldname]" on type "[typename]". Did you mean "[other_fieldname]").

Aan de Gatsby/React kant wil ik wel de uitwerking van die velden implementeren, dus ik kan twee dingen doen.

1. Quickfix

De quickfix is om een pagina / paragraaf te maken waarin alle opties aanwezig zijn. Alle velden zijn gevuld of aangevinkt, waardoor ze meekomen in het schema en de query. Op die manier kun je makkelijk de gewenste uitwerking van die velden bouwen en klaar is Jetje. Maar het is niet gezegd dat in de echte wereld (productie) deze velden ook gevuld zullen zijn. En uiteraard kun je daar ook een pagina maken met alle velden, maar die zal dan ook meekomen naar je productie frontend en dat is niet wenselijk.

2. Slowfix

Optie twee is om het schema van Gatsby handmatig aan te passen middels createSchemaCustomization in gatsby-node.js zodat de velden vooraf gedefinieerd zijn. Dit is een wat complexere oplossing, maar wel de betere. In onderstaand voorbeeld wil ik field_margin_top en field_margin_bottom definiƫren voor paragraph-type "1_column_text".

exports.createSchemaCustomization = ({actions}) => {
    const { createTypes } = actions;

    const typeDefs = `
    type paragraph__1_column_text implements Node {
        field_margin_top: String
        field_margin_bottom: String
    }
    `
    createTypes(typeDefs);
}

Op deze manier maakt het niet uit of het veld een waarde heeft in Drupal, in Gatsby kunnen we er mee vooruit.

back_blog