Fordi vi ikke har GraphQL (ennå)
I en eller annen lys fremtid vil vi bare bruke noe som GraphQL til å dynamisk sette sammen dataforespørsler fra serveren, og hente verken mer eller mindre enn vi trenger. Men den dagen er ikke i dag.
I mellomtiden må vi be om ressurser via det samme API-et som kundene våre bruker, som noen ganger inkluderer støttedata og noen ganger ikke.
Ta for eksempel jobbens sluttpunkt, slik det er representert i Thrift:
Det viser seg at en forespørsel fra API-et om jobbdata vil inkludere matriser av jobbbrukere og dokumenter, og kun referere via fremmednøkler til jobbmaler. Hvis man ser bort fra forretningskonteksten til en jobb, kan man forestille seg en enkel liste over disse jobbene i en sidefelt, hvor valget blir fokuset på hovedpanelet.
Første iterasjon: React Passing Props
Da vi tok vårt første steg med å bygge et brukergrensesnitt rundt dette konseptet, lot vi React ta seg av mye av datahåndteringen, og sendte data – noen ganger ganske mye – videre som rekvisitter til underkomponenter.
La oss fortsette med eksemplet med en liste over jobber (venstre sidefelt ovenfor). Her er en relativt nobel første omgang:
De viktigste tingene med varsler er:
- Foreldrekomponenten mottar som props den gjeldende valgte jobben, en liste over alle jobber og en «idObjectCache» som rett og slett er et manuelt vedlikeholdt dumpingsted for oppslagsdata.
- Forelderen gir all den samme informasjonen til barnet
- Datamisbruk i form av kjedede Underscore-funksjoner i getRows (Unnskyld meg, Lodash, selvfølgelig. Beklager, alle sammen.)
- En liten tullete oppslagsfunksjon i barnet kalt templateIdFromName
Dette er et relativt avgrenset eksempel, men situasjonen kommer raskt ut av kontroll for mer komplekse områder av appen der vi må koble sammen mer ulike dataressurser.
I tillegg viser det seg at hele teammodellen ligger begravd i jobbmodellen, som vi bruker i koden ovenfor ( this.props.job.team.name ), men aldri abstraherer for andre komponenter. På samme sidevisning foretar vi også et API-kall for teamet i den gjeldende jobben.
Andre iterasjon: Henting av fremmednøkkeldata til NuclearJS
Det er ingen hemmelighet. Jeg elsker NuclearJS. Her er et første forsøk på å dumpe Alt til fordel for min nye forelskelse:
Forskjellene er subtile, og viktigheten er kanskje ikke åpenbar hvis du ikke [ennå] har brukt React in sinne.
- Den overordnede beholderen bruker nå kjernefysiske gettere for å hente uforanderlige lister over data med all filtrering og sortering tatt hånd om.
- De eneste propene komponenten mottar er relatert til brukergrensesnittets tilstand (f.eks. «henting av jobber»), men den administrerer sin egen datahenting internt, noe som betyr at komponenten og dens overordnede kan refaktoreres eller flyttes rundt på en sikker måte.
- Jobbmodulen er en vanlig modul som vi bruker i to forskjellige apper, men currentJobId er spesifikk for WebEx-applikasjonen (Web Execution – tilgi den interne sjargongen) og dermed for sin egen modul.
- Vi slipper unna med den mye tryggere getIn() -funksjonen for dyp henting.
Resultatet er mye mindre ordrikt, mye enklere for designerne våre å bruke, style og tilpasse. Flott, men hva med datahentingen?
Administrer fremmednøkkeldata slik Jason Bourne ville gjort
Nuclear-dokumentasjonen tilbyr en flott strategi for å lage API-handlinger modell for modell. Siden innpakningen vi skrev rundt Thrift returns Promises, er mange av modellimplementeringene våre enkle tildelinger:
exports.fetchAll = Thrift.enhanced.JobRolle.index;
Men i tilfeller der vi ønsker å administrere fremmednøkkeldataene for det som kommer tilbake, kan vi raskt avlive fiendene våre slik Jason Bourne ville gjort, slik:
Merk: Det er et par steder i koden ovenfor hvor vi kunne vært mer konsise, men i det minste er det helt klart for den neste ingeniøren (håper jeg!) hva som skjer.
Avskjæring av API-responsen
Det første trikset er at handlingen bruker forskjellige API-endepunkter, avhengig av parameterne som sendes av brukergrensesnittet (dvs. en React-komponent). Fordi Thrift- og Nuclear-funksjonene begge returnerer Promises, kan vi hoppe i midten og sende den resulterende jobs-arrayen til processForeignKeys .
Be om nødvendige fremmednøkkeldata
Det andre trikset er å hente en unik liste over jobbmal-ID-er fra jobblisten (for 50+ jobber kan det hende du bare har 3–4 maler). Et indekskall til maler må pagineres, og i stedet for å hente alle, kan vi sende forespørsler om akkurat det vi trenger. Hvis indeksendepunktet noen gang støtter mottak av en rekke ID-er, kan vi sende det over i ett kall.
Disse handlingene er selvsagt «fire and forget». Våre gettere vil oppdatere React-komponenter gratis når fremmednøkkeldataene ankommer. Rykende varmt.
Laster inn innebygde fremmednøkkeldata
Det tredje trikset er at vi kan ta jobbbrukere, jobbroller og teamdata på tvers av jobber og laste dem inn via en enkel receiveAll-funksjon vi opprettet:
For hver modell later receiveAll-funksjonen som om den håndterer en API-hentingsforespørsel den selv har startet. Resultatene er de samme.
Du har kanskje også lagt merke til ovenfor at når vi behandler dupliserte fremmednøkkeldata på tvers av jobber, kaprer vi uniq() for å ganske enkelt sammenligne ID-er. Dette er mye enklere enn å gjøre en dyp sammenligning, selv om det er avhengig av vår tillit til at serveren ikke vil sende oss forskjellige data med de samme ID-ene i samme forespørsel. Hvis vi ikke kan stole på det, har vi større problemer.
Den siste etappen: Gettere
Du har kommet så langt. La oss få ballen i målsonen.
Formatet for Nuclear getters er litt sukkersøt ved første øyekast, men det er flott.
- The raw job data itself is stored as an Immutable Map of String<jobId> to Map<job>
- JobList observerer jobb- og jobbmaldata, utfører oppslag etter hvert som maler blir tilgjengelige, og returnerer resultatene som en uforanderlig liste.
- Eksportene av activeJobList og completedJobList bruker ganske enkelt filtre og sorteringer slik du ville sett i alle språk/rammeverk. Du får bare enveis databinding gratis.
Til slutt har vi…
- All vår API-kode i en Thrift-innpakning
- Alle API-dataene våre lagres som uforanderlige objekter, administrert fra ende til ende av Nuclear, inkludert avhengigheter av fremmednøkkeldata
- Alt brukergrensesnittet vårt i React med datainnhenting og binding lokalisert så mye som mulig
...som er så enkelt at jeg får tid til å skrive et Medium-innlegg om alt.
Hvis du syntes dette var nyttig, så vær ikke redd for å anbefale det.
Å ja, og vi ansetter vår tredje frontend-ingeniør hvis du har lyst til å få betalt for å fikse litt med React, Nuclear og ImmutableJS hos en Series-A-finansiert oppstartsbedrift støttet av blant annet Andreessen Horowitz, First Round, Kleiner Perkins og Google Ventures. Ta kontakt.











