Programmering

Programmering med Java API'er, del 1: OpenAPI og Swagger

Mens du fik din kaffe, blev Java-applikationsudviklingen ændret--igen.

I en verden drevet af hurtige forandringer og innovation er det ironisk, at API'er comeback. Ligesom det kodende ækvivalent af New York Citys metrosystem i en alder af autonome biler, er API'er det gammel teknologi- gammel, men uundværlig. Hvad der er interessant er, hvordan denne usynlige, daglige it-arkitektur bliver forestillet og brugt i de nuværende teknologitendenser.

Mens API'er er overalt, er de blevet særligt fremtrædende i deres fjerninkarnation som RESTful-tjenester, som er rygraden i skyinstallationer. Cloud-tjenester er offentlige API'er, som er kendetegnet ved offentligt vendende slutpunkter og offentliggjorte strukturer. Cloudbaserede apps går også mod mikrotjenester, som er uafhængige, men relaterede implementeringer. Alle disse faktorer øger API'ernes fremtrædende plads.

I denne todelte tutorial lærer du, hvordan du sætter Java API'er i centrum for din design- og udviklingsproces, fra koncept til kodning. Del 1 starter med en oversigt og introducerer dig til OpenAPI, også kendt som Swagger. I del 2 lærer du, hvordan du bruger Swaggers API-definitioner til at udvikle en Spring Web MVC-app med en Angular 2-frontend.

Hvad er en Java API?

API'er er så almindelige i softwareudvikling, at det undertiden antages, at programmører simpelthen ved, hvad de er. I stedet for at stole på osmose, lad os tage et øjeblik på at pakke ud, hvad vi mener, når vi taler om API'er.

Generelt kan vi sige, at API'er indstiller og styrer grænserne mellem systemer.

Først, API står for "applikationsprogrammeringsgrænseflade." En APIs rolle er at specificere, hvordan softwarekomponenter interagerer. Hvis du er fortrolig med objektorienteret programmering, kender du API'er i deres inkarnation som de grænseflader og klasser, der bruges til at få adgang til underliggende funktioner på sproget, eller som det offentlige ansigt for tredjepartsbiblioteker og OS-kapaciteter.

Generelt kan vi sige, at API'er indstiller og styrer grænserne mellem systemer, som det ses i figur 1.

Matthew Tyson

Så hvor efterlader det os med API-drevet udvikling?

Java API'er til cloud computing, mikrotjenester og REST

Programmering med API'er kommer til udtryk med den moderne web-API: a netværkseksponeret API (NEA), hvor grænsen mellem systemer er "over ledningen." Disse grænser er allerede centrale for webapps, som er det fælles kontaktpunkt mellem front-end-klienter og back-end-servere. Cloudrevolutionen har eksponentielt øget vigtigheden af ​​Java API'er.

Enhver programmeringsaktivitet, der kræver forbrug af cloudtjenester (som grundlæggende er offentlige API'er) og dekonstruktion af systemer til mindre, uafhængige men relaterede implementeringer (også kendt som mikrotjenester), er stærkt afhængig af API'er. Netværkseksponerede API'er er simpelthen mere universelle, lettere opnåede og lettere modificerede og udvidede end traditionelle API'er. Den nuværende arkitektoniske tendens er at udnytte disse funktioner.

Mikrotjenester og offentlige API'er dyrkes fra rødderne til serviceorienteret arkitektur (SOA) og software-as-a-service (SaaS). Selv om SOA har været en tendens i mange år, er udbredt adoption blevet hæmmet af SOAs kompleksitet og faste omkostninger. Branchen har slået sig ned på RESTful API'er som de facto-standarden, hvilket giver lige nok struktur og konvention med mere reel fleksibilitet. Med REST som baggrund kan vi oprette formelle API-definitioner, der bevarer menneskelig læsbarhed. Udviklere skaber værktøj omkring disse definitioner.

Generelt er REST en konvention til kortlægning af ressourcer til HTTP-stier og deres tilknyttede handlinger. Du har sandsynligvis set disse som HTTP GET- og POST-metoder. Hvad der er nøglen er at bruge HTTP i sig selv som standard og lægge konventionelle kortlægninger ovenpå for forudsigelighed.

Brug af Java API'er i design

Du kan se vigtigheden af ​​API'er, men hvordan vil du bruge dem til din fordel?

Brug af Java API-definitioner til at drive design- og udviklingsprocessen er en effektiv måde at strukturere din tænkning på IT-systemer på. Ved at bruge Java API-definitioner lige fra starten af ​​softwareudviklingslivscyklussen (koncept og kravindsamling) opretter du en værdifuld teknisk artefakt, der er nyttig lige indtil implementering såvel som til løbende vedligeholdelse.

Lad os overveje, hvordan Java API-definitioner bygger bro over konceptuelle og implementeringsfaser i udviklingen.

Beskrivende vs receptpligtige API'er

Det er nyttigt at skelne mellem beskrivende og receptpligtige API'er. EN beskrivende API beskriver den måde, koden rent faktisk fungerer, mens a receptpligtig API beskriver hvordan koden skulle gerne fungere.

Begge disse stilarter er nyttige, og begge forbedres i høj grad ved hjælp af et struktureret standardformat til API-definition. Som en tommelfingerregel er anvendelse af API til at drive oprettelse af kode en receptpligtig brug, mens brug af koden til output af Java API-definition er en beskrivende anvendelse.

Krav, der indsamles med Java API'er

På det konceptuelle til implementeringsspektrum er kravindsamling langt forbi på konceptet. Men selv i app-devs konceptfase kan vi begynde at tænke i form af API'er.

Sig, at dit system-i-design beskæftiger sig med mountainbikes - konstruktion, dele osv. Som en objektorienteret udvikler vil du starte med at tale med interessenter om krav. Ret hurtigt efter det ville du tænke på et abstrakt BikePart klasse.

Dernæst ville du tænke igennem webapplikationen, der ville styre de forskellige cykeldeleobjekter. Snart ville du nå frem til fælles krav for at styre disse cykeldele. Her er et øjebliksbillede af kravsfase af dokumentation til en cykeldele-app:

  • Applikationen skal være i stand til at oprette en type cykeldel (gearskifte, bremse osv.).
  • En autoriseret bruger skal være i stand til at liste, oprette og aktivere en deltype.
  • En uautoriseret bruger skal være i stand til at angive aktive deltyper og se lister over individuelle deltypeinstanser i systemet.

Allerede kan du se konturerne af tjenester, der tager form. Med eventuelle API'er i tankerne kan du begynde at skitsere disse tjenester. Som et eksempel er her en delvis oversigt over RESTful CRUD-tjenester til cykeldeltyper:

  • Opret cykeldel type: PUT / del-type /
  • Opdater cykeldel type: POST / del-type /
  • Liste deltyper: GET / del-type /
  • Få deltypedetaljer: GET / del-type /: id

Læg mærke til, hvordan CRUD-tjenesterne begynder at antyde formen på forskellige servicegrænser. Hvis du bygger i en mikrotjenestestil, kan du allerede se tre mikrotjenester ud af designet:

  • En cykeldel service
  • En cykeldel-service
  • En godkendelses- / autorisationstjeneste

Fordi jeg tænker på API'er som grænser for relaterede enheder, Jeg anser mikrotjenesterne fra denne liste for at være API overflader. Sammen tilbyder de et stort billede af applikationsarkitekturen. Detaljer om selve tjenesterne er også beskrevet på en måde, som du vil bruge til den tekniske specifikation, som er den næste fase af softwareudviklings livscyklus.

Teknisk specifikation med Java API'er

Hvis du har inkluderet API-fokus som en del af kravindsamling, har du allerede en god ramme for teknisk specifikation. Det næste trin er at vælge den teknologiestak, du vil bruge til at implementere specifikationen.

Med så meget fokus på at opbygge RESTful API'er har udviklere en forlegenhed over rigdom, når det kommer til implementering. Uanset hvilken stak du vælger, vil udbygning af API'en yderligere på dette trin øge din forståelse af appens arkitektoniske behov. Valgmulighederne kan omfatte en VM (virtuel maskine) til at være vært for applikationen, en database, der er i stand til at styre lydstyrken og typen af ​​data, du serverer, og en skyplatform i tilfælde af IaaS- eller PaaS-implementering.

Du kan bruge API'en til at køre "nedad" mod skemaer (eller dokumentstrukturer n NoSQL) eller "opad" mod UI-elementer. Når du udvikler API-specifikationen, vil du sandsynligvis bemærke et samspil mellem disse bekymringer. Dette er alt sammen godt og en del af processen. API'et bliver et centralt, levende sted at opfange disse ændringer.

En anden bekymring at huske på er, hvilke offentlige API'er dit system vil eksponere. Giv ekstra tanke og pleje til disse. Sammen med at hjælpe med udviklingsindsatsen fungerer offentlige API'er som den offentliggjorte kontrakt, som eksterne systemer bruger til at grænseflade til din.

Offentlige sky-API'er

Generelt definerer API'er kontrakten for et softwaresystem, der giver en kendt og stabil grænseflade, som andre systemer kan programmeres mod. Specifikt er en offentlig sky API en offentlig kontrakt med andre organisationer og programmører, der bygger systemer. Eksempler er GitHub og Facebook API'er.

Dokumentering af Java API

På dette tidspunkt vil du begynde at fange dine API'er i formel syntaks. Jeg har angivet et par fremtrædende API-standarder i tabel 1.

Sammenligning af API-formater

 
NavnResuméStjerner på GitHubURL
OpenAPIJSON og YML-understøttet API-standard, der stammer fra Swagger-projektet, indeholder forskellige værktøjer i Swagger-økosystemet.~6,500//github.com/OAI/OpenAPI-Specification
RAMLYML-baseret spec understøttes hovedsageligt af MuleSoft~3,000//github.com/raml-org/raml-spec
API BluePrintEt API-designsprog ved hjælp af MarkDown-lignende syntaks~5,500//github.com/apiaryio/api-blueprint/

Næsten ethvert format, du vælger til dokumentation af din API, skal være okay. Se bare efter et format, der er struktureret, har en formel spec og et godt værktøj omkring det, og ser ud til at det vil blive opretholdt aktivt på lang sigt. Både RAML og OpenAPI passer til denne regning. Et andet pænt projekt er API Blueprint, der bruger markdown-syntaks. For eksempler i denne artikel skal vi bruge OpenAPI og Swagger.

OpenAPI og Swagger

OpenAPI er et JSON-format til beskrivelse af REST-baserede API'er. Swagger startede som OpenAPI, men har udviklet sig til et sæt værktøjer omkring OpenAPI-formatet. De to teknologier supplerer hinanden godt.

Introduktion til OpenAPI

OpenAPI er i øjeblikket det mest almindelige valg til oprettelse af RESTful-definitioner. Et overbevisende alternativ er RAML (RESTful API Markup Language), der er baseret på YAML. Personligt har jeg fundet værktøjet i Swagger (især den visuelle designer) mere poleret og fejlfrit end i RAML.

OpenAPI bruger JSON-syntaks, som de fleste udviklere kender. Hvis du hellere ikke vil anstrenge dine øjne ved at analysere JSON, er der brugergrænseflader, der gør det lettere at arbejde med det. Del 2 introducerer brugergrænseflader til RESTful-definitioner.

Fortegnelse 1 er et eksempel på OpenAPIs JSON-syntaks.

Notering 1. OpenAPI-definition til en simpel BikePart

 "stier": {"/ part-type": {"get": {"description": "Henter alle de deltyper, der er tilgængelige i systemet", "operationId": "getPartTypes", "producerer": ["applikation / json "]," response ": {" 200 ": {" description ":" Henter BikeParts "," schema ": {" type ":" array "," items ": {" $ ref ":" # / definitioner / BikePart "}}}}}}} 

Denne definition er så kortfattet, at den praktisk talt er spartansk, hvilket er fint for nu. Der er masser af plads til at øge detaljerne og kompleksiteten af ​​API-definitionen fremover. Jeg viser dig snart en mere detaljeret gengivelse af denne definition.

Kodning fra Java API

Kravindsamling er færdig, og den grundlæggende app er blevet specificeret, hvilket betyder at du er klar til den sjove del --- kodning! At have en formel Java API-definition giver dig nogle tydelige fordele. For det første ved du, hvilke slutpunkter back-end og front-end-udviklere har brug for at oprette og kode mod henholdsvis. Selvom du er et team af en, vil du hurtigt se værdien af ​​en API-drevet tilgang, når du begynder at kode.

Når du bygger applikationen op, kan du også se værdien af ​​at bruge API'er til at fange frem og tilbage forhandling mellem udvikling og forretning. Brug af API-værktøjer vil fremskynde både anvendelse og dokumentation af kodeændringer.

Mere detaljerede specifikationer og faktisk kodning kan kræve større detaljer end den kortfattede definition i lister 1. Derudover kan større og mere komplekse systemer fortjene funktioner, der skaleres, som dokumentreferencer. Fortegnelse 2 viser et mere detaljeret eksempel på BikePart API.

Liste 2. Tilføjelse af detaljer til BikePart API-definitionen

 "stier": {"/ part-type": {"get": {"description": "Henter alle de deltyper, der er tilgængelige i systemet", "operationId": "getPartTypes", "producerer": ["applikation / json "]," parameters ": [{" name ":" limit "," in ":" query "," description ":" maksimum antal resultater, der skal returneres "," required ": false," type ": "heltal", "format": "int32"}], "response": {"200": {"description": "part-type listing", "schema": {"type": "array", "items ": {" $ ref ":" # / definitions / PartType "}}}," default ": {" description ":" uventet fejl "," schema ": {" $ ref ":" # / definitions / Error " }}}} 
$config[zx-auto] not found$config[zx-overlay] not found