Programmering med Java API: er, del 1: OpenAPI och Swagger

Medan du fick ditt kaffe förändrades Java-applikationsutvecklingen - igen .

I en värld som drivs av snabb förändring och innovation är det ironiskt att API: er gör comeback. Precis som kodningsekvivalenten för New York Citys tunnelbanesystem i en ålder av autonoma bilar, är API: er gammalt tekniskt - gammalt men oumbärligt. Det som är intressant är hur denna osynliga, vardagliga IT-arkitektur tänks om och används i nuvarande teknologitrender.

Medan API: er finns överallt har de blivit särskilt framträdande i sin fjärrinkarnation som RESTful-tjänster, som är ryggraden i molndistributionerna. Molntjänster är offentliga API: er , som kännetecknas av slutpunkter som är offentliga och publicerade strukturer. Molnbaserade appar trenderar också mot mikrotjänster , som är oberoende men relaterade distributioner. Alla dessa faktorer ökar framträdandet av API: er.

I denna tvådelade handledning lär du dig hur du sätter Java API: er i hjärtat av din design- och utvecklingsprocess, från koncept till kodning. Del 1 börjar med en översikt och introducerar dig till OpenAPI, även känd som Swagger. I del 2 lär du dig hur du använder Swaggers API-definitioner för att utveckla en Spring Web MVC-app med en Angular 2-front.

Vad är ett Java API?

API: er är så vanliga vid programutveckling att det ibland antas att programmerare helt enkelt vet vad de är. I stället för att lita på osmos, låt oss ta en minut att packa upp vad vi menar när vi pratar om API: er.

Generellt kan vi säga att API: er ställer in och hanterar gränserna mellan system.

För det första står API för "applikationsprogrammeringsgränssnitt." En API: s roll är att ange hur programvarukomponenter interagerar. Om du är bekant med objektorienterad programmering känner du API: er i deras inkarnation som gränssnitt och klasser som används för att få tillgång till underliggande funktioner i språket, eller som den offentliga ansikten för tredjepartsbibliotek och OS-funktioner.

Generellt kan vi säga att API: er ställer in och hanterar gränserna mellan system, vilket framgår av figur 1.

Matthew Tyson

Så var lämnar det oss med API-driven utveckling?

Java API: er för molntjänster, mikrotjänster och REST

Programmering med API: er kommer i förgrunden med det moderna webb-API: ett nätverksexponerat API (NEA) , där gränsen mellan system är "över kabeln." Dessa gränser är redan centrala för webbappar, som är den gemensamma kontaktpunkten mellan front-end-klienter och back-end-servrar. Molnrevolutionen har exponentiellt ökat betydelsen av Java API: er.

Varje programmeringsaktivitet som kräver konsumtion av molntjänster (som i grunden är offentliga API: er) och dekonstruering av system till mindre, oberoende men relaterade distributioner (även känd som mikrotjänster) är beroende av API: er. Nätverksexponerade API: er är helt enkelt mer universella, lättare att få och lättare att modifiera och utöka än traditionella API: er. Den nuvarande arkitektoniska trenden är att dra nytta av dessa funktioner.

Mikrotjänster och offentliga API: er växer från rötterna till serviceorienterad arkitektur (SOA) och mjukvara som en tjänst (SaaS). Även om SOA har varit en trend under många år, har en omfattande adoption blivit försvagad av SOA: s komplexitet och allmänna kostnader. Branschen har bestämt sig för RESTful API: er som de facto-standarden, vilket ger tillräckligt med struktur och konvention med mer verklig flexibilitet. Med REST som bakgrund kan vi skapa formella API-definitioner som bibehåller mänsklig läsbarhet. Utvecklare skapar verktyg kring dessa definitioner.

I allmänhet är REST en konvention för mappning av resurser till HTTP-sökvägar och tillhörande åtgärder. Du har sannolikt sett dessa som HTTP GET- och POST-metoder. Vad som är nyckeln är att använda HTTP själv som standard och lagra konventionella mappningar utöver det för förutsägbarhet.

Använda Java API: er i design

Du kan se vikten av API: er, men hur skulle du använda dem till din fördel?

Att använda Java API-definitioner för att driva design- och utvecklingsprocessen är ett effektivt sätt att strukturera ditt tänkande om IT-system. Genom att använda Java API-definitioner från början av livscykeln för programvaruutveckling (koncept och kravinsamling) skapar du en värdefull teknisk artefakt som är användbar ända till distribution, liksom för löpande underhåll.

Låt oss överväga hur Java API-definitioner överbryggar koncept- och implementeringsstadierna för utvecklingen.

Beskrivande vs receptbelagda API: er

Det är bra att göra en åtskillnad mellan beskrivande och föreskrivande API: er. Ett beskrivande API beskriver hur koden faktiskt fungerar, medan ett föreskrivande API beskriver hur koden ska fungera.

Båda dessa stilar är användbara och båda förbättras kraftigt genom att använda ett strukturerat standardformat för API-definition. Som en tumregel är att använda API för att driva kodskapande en receptbelagd användning, medan användning av koden för att mata ut Java API-definitionen är en beskrivande användning.

Krav som samlas med Java API: er

På det konceptuella till implementeringsspektrumet är kravuppsamlingen långt över på konceptets sida. Men även i den konceptuella fasen av apputveckling kan vi börja tänka i termer av API: er.

Anta att ditt system i design handlar om mountainbikes - konstruktion, delar och så vidare. Som en objektorienterad utvecklare bör du börja med att prata med intressenter om krav. Ganska snabbt efter det skulle du tänka på en abstrakt BikePartklass.

Därefter skulle du tänka igenom webbapplikationen som skulle hantera de olika cykeldelobjekten. Snart skulle du komma fram till vanliga krav för att hantera dessa cykeldelar. Här är en ögonblicksbild av kraven i dokumentationen för en cykeldelapp:

  • Applikationen måste kunna skapa en typ av cykeldel (växelspak, broms, etc.).
  • En auktoriserad användare måste kunna lista, skapa och göra en deltyp aktiv.
  • En obehörig användare måste kunna lista aktiva deltyper och visa listor över enskilda deltyper i systemet.

Redan kan du se konturerna av tjänster som tar form. Med eventuella API: er i åtanke kan du börja skissera dessa tjänster. Som ett exempel, här är en partiell lista över RESTful CRUD-tjänster för cykeldeltyper:

  • Skapa typ av cykeldel: PUT /part-type/
  • Uppdatera typ av cykeldel: POST /part-type/
  • Lista deltyper: GET /part-type/
  • Hämta detalj av detaljtyp: GET /part-type/:id

Lägg märke till hur CRUD-tjänsterna börjar leda till formen på olika servicegränser. Om du bygger i en mikrotjänststil kan du redan se tre mikrotjänster fram från designen:

  • En cykeldel service
  • En cykeldelservice
  • En autentisering / auktoriseringstjänst

Eftersom jag tänker på API: er som gränser för relaterade enheter , anser jag att mikrotjänsterna från den här listan är API-ytor . Tillsammans erbjuder de en storbildsvy av applikationsarkitekturen. Detaljer om själva tjänsterna beskrivs också på ett sätt som du kommer att använda för den tekniska specifikationen, som är nästa fas av programvaruutvecklingslivscykeln.

Teknisk specifikation med Java API: er

Om du har inkluderat API-fokus som en del av kravinsamlingen har du redan ett bra ramverk för teknisk specifikation. Nästa steg är att välja teknikstack som du kommer att använda för att implementera specifikationen.

Med så mycket fokus på att bygga RESTful API: er har utvecklare en förlägenhet av rikedom när det gäller implementering. Oavsett vilken stack du väljer, kommer utbyggnaden av API: et ytterligare i detta skede att öka din förståelse för appens arkitektoniska behov. Alternativ kan innehålla en virtuell dator (virtuell maskin) för att vara värd för applikationen, en databas som kan hantera volymen och typen av data du serverar och en molnplattform i fallet med IaaS- eller PaaS-distribution.

Du kan använda API: et för att köra "nedåt" mot scheman (eller dokumentstrukturer n NoSQL) eller "uppåt" mot UI-element. När du utvecklar API-specifikationen kommer du sannolikt att märka ett samspel mellan dessa problem. Allt detta är bra och en del av processen. API: et blir en central, levande plats för att fånga dessa förändringar.

Ett annat problem att tänka på är vilka offentliga API: er som ditt system kommer att exponera. Tänk extra på och ta hand om dessa. Tillsammans med att hjälpa till i utvecklingsarbetet fungerar offentliga API: er som det publicerade kontraktet som externa system använder för att gränssnitt med ditt.

Offentliga moln-API: er

I allmänhet definierar API: er kontraktet för ett mjukvarusystem, vilket ger ett känt och stabilt gränssnitt mot vilket andra system kan programmeras. Specifikt är ett offentligt moln-API ett offentligt kontrakt med andra organisationer och programmerare som bygger system. Exempel är GitHub och Facebook API: er.

Dokumentera Java API

I det här skedet vill du börja fånga dina API: er i formell syntax. Jag har listat några framstående API-standarder i tabell 1.

Jämför API-format

 
namn Sammanfattning Stjärnor på GitHub URL
OpenAPI JSON och YML-stödd API-standard härstammar från Swagger-projektet, innehåller olika verktyg i Swagger-ekosystemet. ~ 6500 //github.com/OAI/OpenAPI-Specification
RAML YML-baserad specifikation som främst stöds av MuleSoft ~ 3000 //github.com/raml-org/raml-spec
API BluePrint Ett API-designspråk som använder MarkDown-liknande syntax ~ 5500 //github.com/apiaryio/api-blueprint/

Praktiskt taget alla format du väljer för att dokumentera ditt API borde vara okej. Leta bara efter ett format som är strukturerat, har en formell specifikation och bra verktyg kring det och ser ut som att det kommer att bibehållas aktivt på lång sikt. Både RAML och OpenAPI passar den fakturan. Ett annat snyggt projekt är API Blueprint, som använder markdown-syntax. För exempel i den här artikeln ska vi använda OpenAPI och Swagger.

OpenAPI och Swagger

OpenAPI är ett JSON-format för att beskriva REST-baserade API: er. Swagger började som OpenAPI, men har utvecklats till en uppsättning verktyg runt OpenAPI-formatet. De två teknologierna kompletterar varandra väl.

Introduktion till OpenAPI

OpenAPI är för närvarande det vanligaste valet för att skapa RESTful-definitioner. Ett övertygande alternativ är RAML (RESTful API Markup Language), som är baserat på YAML. Personligen har jag hittat verktyget i Swagger (särskilt den visuella designern) mer polerat och felfritt än i RAML.

OpenAPI använder JSON-syntax, vilket är känt för de flesta utvecklare. Om du hellre inte vill tänka på att analysera JSON finns det användargränssnitt som gör det lättare att arbeta med det. Del 2 introducerar användargränssnitt för RESTful-definitioner.

Listning 1 är ett exempel på OpenAPIs JSON-syntax.

Listing 1. OpenAPI-definition för en enkel BikePart

 "paths": { "/part-type": { "get": { "description": "Gets all the part-types available in the system", "operationId": "getPartTypes", "produces": [ "application/json" ], "responses": { "200": { "description": "Gets the BikeParts", "schema": { "type": "array", "items": { "$ref": "#/definitions/BikePart" } } } } } } } 

Denna definition är så kortfattad att den praktiskt taget är spartansk, vilket är bra för nu. Det finns gott om utrymme för att öka detaljrikedomen och komplexiteten i API-definitionen framöver. Jag visar dig en mer detaljerad iteration av denna definition inom kort.

Kodning från Java API

Kravssamlingen är klar och den grundläggande appen har specificerats, vilket innebär att du är redo för den roliga delen --- kodning! Att ha en formell Java API-definition ger dig några tydliga fördelar. För det första vet du vilka slutpunkter backend-och front-end-utvecklare behöver skapa respektive koda mot. Även om du är ett team av en, ser du snabbt värdet av ett API-driven tillvägagångssätt när du börjar koda.

När du bygger ut applikationen ser du också värdet av att använda API: er för att fånga fram och tillbaka förhandlingar mellan utveckling och företag. Användning av API-verktyg kommer att påskynda både tillämpning och dokumentation av kodändringar.

Mer detaljerade specifikationer och faktisk kodning kan kräva mer detaljer än den kortare definitionen i Listing 1. Dessutom kan större och mer komplexa system förtjäna funktioner som kan skalas, som dokumentreferenser. Listning 2 visar ett mer detaljerat exempel på BikePart API.

Lista 2. Lägga till detaljer i BikePart API-definitionen

 "paths": { "/part-type": { "get": { "description": "Gets all the part-types available in the system", "operationId": "getPartTypes", "produces": [ "application/json" ], "parameters": [ { "name": "limit", "in": "query", "description": "maximum number of results to return", "required": false, "type": "integer", "format": "int32" } ], "responses": { "200": { "description": "part-type listing", "schema": { "type": "array", "items": { "$ref": "#/definitions/PartType" } } }, "default": { "description": "unexpected error", "schema": { "$ref": "#/definitions/Error" } } } }