Skamløs reklame: Jeg jobber på WI ( http://wi.co/ ). Vi forandrer måten folk utenfor Silicon Valley jobber på. Hvis du er interessert, kan du ta en titt på karrieresiden vår ( http://wi.co/careers ) eller sende meg en e-post på [email protected].

Om Thrift: Hvis du ikke er kjent med RPC eller Thrift, kan det være lurt å ta en titt på https://thrift.apache.org/

Så, et problem jeg har hørt er: «Hei, så vi publiserer Thrift API-ene våre til tredjepartsleverandører, og vi trenger at det skal være enkelt å bruke.» Nå kan du enten:

  1. Avslør Thrift-endepunktene og veiled API-forbrukerne dine i Thrift og hjelp dem med å feilsøke eventuelle problemer.
  2. Du vedlikeholder et bibliotek som er dekket av de ulike Thrift-tjenestene for hvert språk/plattform du ønsker å støtte.
  3. Lag en måte å manuelt konvertere mellom menneskelig lesbar JSON til Thrift og omvendt, og vedlikehold den for hver enkelt struktur, tjeneste og funksjon.

Hvis disse alternativene høres lite tiltalende ut for deg, har du rett – de kan være mye arbeid. Men finnes det en annen måte?

Jeg vil bruke følgende enkle Thrift-fil i artikkelen min nedenfor:

Thrift støtter en JSON-protokoll som overfører data som JSON mellom klienten og serveren (dette er det vi bruker for webgrensesnittet vårt). Men et blikk på dataene som sendes vil fortelle deg at det ikke vil være mulig å eksponere dette for tredjeparter:

Og dette er for en veldig enkel samtale: logg inn (e-post, passord) .

Thrift JSON har en hel haug med sjargong den bruker for å analysere det eksakte kallet, som typene til hvert argument/felt, lengden på arrayer/sett, nøkkelnummeret til hvert felt i en struktur, osv.

Så vi fant en måte å konvertere menneskelig lesbar JSON til Thrift uten å:

  1. Legger til en hel haug med sjargong
  2. Utfører vedlikehold. Eventuelle endringer i Thrift-definisjonene skal automatisk kunne brukes.

Et eksempel på samme anrop ved bruk av den nye metoden:

Mye mer lesbart!

Formatet er enkelt. Metodenøkkelens verdier skal være det nøyaktige navnet på metoden i Thrift-definisjonen. Arguments-objektet er listen over argumenter. Nøklene i Arguments-objektet er igjen de samme som navnet på funksjonsparametrene i Thrift-definisjonen.

Her er et eksempel på et svar:

Et eksempel på et API-definert unntak som ble kastet:

Merk at den enkelt kan håndtere strukturer (og strukturer innebygd i strukturer) også. Over currentUser er det en struktur. I JSON er det ganske enkelt et JSON-objekt med nøkler som er de samme som feltnavnene i definisjonen av Thrift Struct.

I tillegg er err (unntaket) ovenfor også en struktur, siden unntak i Thrift rett og slett er spesielle typer strukturer.

Furthermore, note that the success object itself is a struct. Its is an auto generated struct whose name is usually <MethodName>_result (in this case login_result). You can see it if you ever peek into the generated code for any other language. It has two fields: result for a successful call and err for any api defined error that was thrown.

Similarly, the arguments is also an auto generated Struct, usually call <MethodName>_args (in this case login_args). Its fields are simply the function arguments. Thus, this format follows very closely to how actual Thrift works.

Det finnes en JSON-generator for Thrift, som genererer alle metadataene til

  1. Tjenester: navn, liste over funksjoner
  2. Funksjoner: navn, argumentliste
  3. Strukturer: navn, felt sammen med navn og typer

Nedenfor er et eksempel på de genererte metadataene for Thrift-filen ovenfor.

Jeg brukte disse metadataene i en ny protokoll. En protokoll er måten Thrift marshalerer og un-marshalerer data på. Problemet er at protokoller i Thrift er sterkt typebestemte. Den må kunne sende opp den nøyaktige typen felt (eller elementtypen til arrayet eller nøkkel- og verditypen til kartet) og andre ting som størrelsen på kartet eller arrayet. Det er derfor Thrift JSON-protokollen har så mye sjargong inni seg. Den inneholder nettopp denne informasjonen.

Denne nye protokollen , HumanReadableJsonProtocol , bruker JSON-en som klienten sender opp sammen med metadataene fra Thrift JSON-generatoren for å finne ut nøyaktig hvilken funksjon som ble kalt, hvilke argumenter som ble sendt og hva deres eksakte typer er.

For eksempel, i kallet ovenfor vil den først slå opp metadataene for login- metoden. Deretter vil den for hver nøkkel i argument -objektet i klient-JSON finne den tilhørende nøkkelen i argument- arrayet i metadataene. Avhengig av typen vil den analysere den (hvis det er en struktur, liste eller kart, vil den fortsette å rekurdere til den når en basistype – int, streng, boolsk, double osv.). For eksempel, i dette tilfellet vil den se etter et objekt hvis « navn» -verdi er « e-post» i metadataene, se om det har en strengtype og deretter bekrefte at verdien av « e-post» i argument- objektet i klient-JSON også er en streng. Tilsvarende for « passord».

Denne nye HumanReadableJsonProtocol er fortsatt sterkt typebestemt. Hvis du sender opp en nøkkel hvis verdi ikke tilordnes riktig til typen som er definert i metadataene, vil det gi en feil.

Her er en feil som oppstår i et slikt tilfelle, der jeg prøvde å sende et tall i stedet for en streng til passordfeltet :

Merk at denne JSON-en har en unntaksnøkkel . De ovennevnte hadde en resultatnøkkel etterfulgt av enten suksess eller feil. Dette ligner på hvordan Thrift behandler de forskjellige svartypene. Du får enten tilbake et resultat eller et unntak . Resultat betyr at kallet var vellykket, og ingen andre feil enn API-definerte feil (de i metodesignaturen) ble kastet. Dermed har Resultat to felt: ett for suksess , som inneholder det vellykkede resultatet av kallet, og ett for feil , som inneholder den API-definerte feilen som ble kastet. Unntak inneholder alle andre feil (inkludert Thrift-feil som ødelagte data, ute av stand til å analysere data, feil typer osv.).

Siden det bare er en protokoll (måte å samle/av-samle data på), vil den Thrift-genererte koden som bruker den automatisk ta seg av ting som obligatoriske eller valgfrie felt.

Så hvis for eksempel forespørselen har innholdstypen application/json, trenger du bare å bruke HumanReadableJsonProtocol til å analysere den. Ellers kan du bruke standardprotokollen du bruker. Du må også legge inn katalogen der de genererte JSON-metadataene finnes.

Til slutt bruker den automatisk eventuelle nye endringer i Thrift-definisjonene (så lenge du også genererer JSON-en ved hjelp av JSON-generatoren).

Her er kildekoden til prosjektet: HumanReadableJsonProtocol

Hvis du ønsker koden for dette, eller ønsker å hjelpe til med å utvide koden for flere språk og skrive tester for det, kan du kontakte meg.

HumanReadableJsonProtocol-snippet i Ruby

Her er et utdrag av koden som utfører parsingen i Ruby:


Skamløs reklame igjen: Jeg jobber på WI ( http://wi.co/ ). Vi forandrer måten folk utenfor Silicon Valley jobber på. Hvis du er interessert, kan du ta en titt på karrieresiden vår ( http://wi.co/careers ) eller sende meg en e-post på [email protected]

Takk til Adam Neary .