Open API Specifikace
Článek se vztahuje k verzi produktu OAS 3.0
Tento článek byl napsán v roce 2022. Vývojářské technologie se neustále inovují a článek již nemusí popisovat aktuální stav technologie, ideální řešení a můj současný pohled na dané téma.
Přestože REST API patří dnes mezi nejrozšířenější rozhraní pro výměnu dat mezi informačními systémy, od svých počátků bojují s formálním popisem. Velká výhoda v podobě použití nosného protokolu HTTP je svým způsobem i prokletím. Ačkoliv je protokol standardizován, nestačí to pro návrh API, která by vypadala na všech platformách jakkoliv standardizovaně. Situace se nelepší a nejspíš ani nezlepší. Jediná šance, jak vnést do REST API alespoň nějaký řád je použít specifikaci OAS.
Obsah článku
- První snahy o popis REST API v .NETu
- Myslíme metodou Specification First
- Automatizace trochu drhne
- Píšeme Open API Specifikaci
- Struktura OAS
- Závěr
První snahy o popis REST API v .NETu
Když vývojáři nasadí své API na vybranou URL, nikdo v podstatě neví, z jakých endpointů se celé API skládá, jaké parametry je možné na dané URL používat, jaké užít HTTP metody a natož pak jaké proti danému endpointu posílat struktury. Implementátor s ohledem na definici REST API vlastně ani neví, zda může poslat JSON, XML nebo třeba Protobuf.
Je několik cest, jak se s tím vypořádat. K danému REST API lze vytvořit tzv. SDK, které je vydáno pro vybrané platformy. V prostředí .NETu si takové SDK vývojář stáhne do projektu formou NuGet balíčku a v objektové podobě následně s API komunikuje. Na podobném principu je postavena celá řada API z prostředí Microsoft Azure. To ale znamená zodpovědnost týmu za udržování všech SDK s ohledem na API. Další možnost je sepsat jednoduchou dokumentaci, kde se API popíše. Vedle cáru papíru dává samozřejmě smysl elektronická podoba. Může to být PDF, HTML nebo jakkoliv jinak upravená dokumentace. Dokumentaci mohou používat vývojáři na všech platformách a integrovat se tak snadno na dané REST API. Nepříjemné je, že každou změnu v API musí vývojář v dokumentaci ručně upravovat. A právě proto vznikla možnost generovat si dokumentaci k REST API z kódu.
V roce 2014 byla vydána sada knihoven, které rozšířily schopnosti webového frameworku ASP.NET o mnoho funkcí souvisejících s vývojem REST API. Microsoft je zabalíkoval do šablony s názvem ASP.NET Web API 2. Součástí webového frameworku byl a stále je tzv. ApiExplorer, který umožňuje prozkoumat controllery včetně všech možných atributů, parametrů a vstupních i výstupních modelů. Právě nad touto funkcionalitou byl postaven komunitní projekt ASP.NET Help Pages, který přidal do API projektu novou areu v podobě dokumentace REST API. Vývojář měl navíc možnost do jednotlivých HTML a CSS zasahovat a dokumentaci si přizpůsobit podle svých potřeb.
Podobný osud měla REST API na různých platformách. Pro implementující stranu to vždy znamenalo prohrabávání se rozsáhlou dokumentací, ruční vývoj API klientů a dlouhé hodiny strávené laděním různých implementačních detailů, kterými se jednotlivé platformy odlišují.
Myslíme metodou Specification First
Automatické generování dokumentace má své nevýhody. V případě platformy .NET musí vývojář naprogramovat veškeré controllery, přichystat modely a odekorovat je validačními atributy. Ani na konci této úmorné práce nevznikne příliš lichotivá dokumentace. Generovaný seznam endpointů neobsahuje podrobný popis endpointů, chybí reálné ukázky požadavků a odpovědí a některé specifické vlastnosti API ani nelze popsat. Možnosti generátorů jsou velmi omezené. Když se navíc vývojář rozhodne změnit technologii (stačí zahodit MVC), nic se jednoduše nikde nevygeneruje.
Další velký problém je, že dokumentace se generuje z kódu. Musí tedy vzniknout alespoň základní implementační kostra, abychom měli popis nového API. Bez vývojářské práce tedy nemáme absolutně žádný popis REST API. A nakonec i kdybychom měli popis REST API na základě implementace, získáme spíše dokumentaci než specifikaci. Když vývojář udělá v kódu chybu, ta se jednoduše promítne do automaticky generované dokumentace a implementátor může mít pocit, že chování API je správně. Generování dokumentace z kódu se hodí skutečně jen pro případy, když už někde leží REST API, ke kterému chceme vygenerovat jeho popis.
Důsledkem popsaných nevýhod byla snaha o možnost formálního popisu REST API bez závislosti na jakékoliv implementaci. Za poslední dekádu vzniklo několik pokusů, z nichž nejrozšířenější jsou specifikace API Blueprint, RAML a Swagger. Dnes už není potřeba si vybírat, protože jasným vítězem tohoto souboje je Swagger, známý jako Open API Specification (OAS). Ten umožňuje popsat REST API pomocí formátu JSON nebo YAML. Kolem OAS již vzniklo mnoho nástrojů na všech myslitelných platformách.
Existence specifikace dává vývojářským týmům svobodu. Specifikace nového REST API může vznikat nezávisle na implementaci. Tvůrci API se mohou nad specifikací bavit s konzumenty API a vytvářet jeho podobu bez toho, aniž by musel vzniknout jediný řádek programového kódu. Hotovou specifikaci lze dle potřeby verzovat a jednotlivé verze mohou paralelně vývojářské týmy implementovat. Specifikace je tedy dohodou o podobě API a předlohou pro implementaci. Tento přístup se dnes označuje často jako Design First nebo Specification First.
Automatizace trochu drhne
Výhodou OAS je, že umožňuje strojové zpracování. Na základě jednoho JSON či YAML souboru lze vygenerovat API klienty v různých jazycích nebo například základní podobu API serveru či mock serveru. Použít ji lze ale i pro pouhé vygenerování tříd v různých jazycích. V praxi automatizace OAS naráží na několik problémů. První z nich je ten, že vývojáři nenavrhují API metodou Specification First, ale OAS soubor si generují z kódu. Už jsme si vysvětlili, že možnosti generování na různých platformách jsou omezené a vygenerovaná OAS je v konečném důsledku polovičatá. Polovičatá specifikace je špatným sluhou pro další automatizaci.
Další potíž je čistě technického charakteru. Vývojářské firmy (např.: Microsoft, Oracle) neustále zásobují vývojáře novými verzemi frameworků a nástroje pro generování kódu z OAS nejsou dostatečně rychle aktualizovány. Navíc mnoho platforem přináší svobodu při volbě programovacího paradigmatu (MVC, Minimal API) nebo volbě serializeru (Newtonsoft, Microsoft). To znamená několik různých kombinací nastavení, které musí automatizační nástroje podporovat. A samozřejmě je nepodporují. Automatizace tak zpravidla umožní vygenerovat prvotní hrubý kód, který je nutné ručně učesat. Tím se však vývojář odřízne od možnosti efektivně kód v případě změny specifikace přegenerovat.
Aby problémů nebylo málo, nástroje jsou primárně vydávány a aktualizovány v podobě CLI. To vyhovuje vývojářům po celém světě snad na všech myslitelných platformách. Jedinou mně známou výjimkou jsou .NET vývojáři na Windows, kteří z nějakého důvodu příkazovou řádku bojkotují. Naštěstí situace kolem DevOps a obecně .NETu se rychle mění a vývojářům během blízkých měsíců a let nezbyde než se s CLI nástroji sžít. Grafická rozhraní a webové nástroje postavené nad těmito nástroji jsou totiž co se aktualizace týče až na konci pomyslného procesu. Aktuální verze specifikace (3.1) byla představena v únoru roku 2021. Nová specifikace přinesla mj. nový element Webhooks. Dnes, téměř po roce, neznám žádný nástroj, který by tuto novou funkcionalitu řádně podporoval.
Píšeme Open API Specifikaci
Rád bych vývojáře přesvědčil, že nejlepší co mohou pro své nové REST API udělat, je nezávisle na implementaci ho navrhovat s pomocí OAS. Přes veškeré popsané nedostatky je OAS nejlepší řešení pro popis REST API. Jenomže ani tady nemám dobrou zprávu. Jediným řešením s absolutní podporou OAS je v podstatě otevřít notepad a ručně psát YAML. Usnadnit práci může jen Visual Studio Code s různými pluginy. Některé podporují jazyk YAML, jiné umí generovat určité fragmenty OAS a další dokáží vykreslovat na základě OAS vizuální dokumentaci. Zejména na platformě .NET to není důvod k oslavám. Firmy si pěstují mnoho přetížených full-stack vývojářů a představa, že se musí učit ještě novou specifikaci není nikomu po chuti.
Existuje i mnoho vizuálních nástrojů, ve kterých si lze REST API naklikat. Jsou bohužel z pochopitelných důvodů často zpoplatněné a ne vždy plně pokrývají všechny schopnosti OAS. Když k tomu přidáme speciální funkce jako týmová správa, verzování, testování endpointů a mockování, situace začne být o to svízelnější. Jako zlatý standard firmy často používají Postman, který nabízí nejrozsáhlejší arzenál funkcí, ovšem za ne zcela příznivých cenových podmínek. V případě designu REST API na základě OAS je dle mého názoru nejdále Stoplight. Nabízí zdarma vizuální designér, dokumentaci a mock servery. Pokročilejší funkce pak nabízí v cenově příznivých balíčcích.
Struktura OAS
Aktuální OAS je označena verzí 3.1.0 a umožňuje popis pomocí formátu JSON a YAML. Rootové dokumenty se doporučuje označovat jako openapi.json nebo openapi.yaml. Základní podporované datové typy vychází z RFC a zahrnují různé formáty celých a desetinných čísel a řetězců. V případě řetězce lze upřesnit například i formát (datum, čas, uri, email, heslo, a další..). Schéma OAS se skládá z několika hlavních částí, například:
- openapi - povinné, verze OAS
- info - povinné, metadata o REST API
- servers - seznam serverů, kde je API dostupné (produkce, test, ...)
- paths - endpointy, respektive operace
- components - sdílená schémata, JSON kontrakty
- security - bezpečnostní mechanismy
- tags - tagy pro třídění paths do skupin
Každá z výše uvedených částí je v podstatě objekt, který je definován svým vlastním schématem. Některé prvky jsou povinné, jiné lze uvést volitelně. OAS je navržena pro potřeby REST rozhraní, proto v případě endpointů vytváří logickou hierarchickou strukturu:
- relativní cesta k resource
- HTTP metody
- odpovědi - status kódy
- formáty odpovědi
- odpovědi - status kódy
- HTTP metody
Jednotlivé endponty lze samozřejmě doplnit o různé popisky, přičemž vývojář má k dispozici i podporu syntaxe markdown. U jednotlivých API endpointů lze definovat parametry, vstupní podobu zpráv včetně validačních pravidel, bezpečnostní nastavení a další možnosti. Dokumentace je velmi bohatá a nabízí mnoho ukázek jak v JSONu tak YAMLu. Při definování odpovědí lze využít i pokročilé diskriminátory, které umožňují definovat více možných druhů odpovědí. K jednotlivým kontaktům lze dopisovat i smysluplné ukázky.
Ruční psaní OAS není zpočátku rychlé, lze si ale na syntaxi zvyknout. Mnoho částí specifikace lze navíc časem metodou copy-paste rychle rozkopírovat. Moderní nástroje umožňují OAS dokument i rozdělit a držet tak na jednom místě endpointy a na jiném například podobu kontraktů.
Závěr
Máte-li ve firmě REST API staršího data, možná si vystačíte s pouhým vygenerováním dokumentace. S vysokou pravděpodobností nebude výsledek nijak oslnivý. Hledáte-li možnost, jak navrhovat REST API seriózně, dříve než vznikne implementace a chcete ho pokrýt standardem, sáhněte jednoznačně po OAS. OAS poskytuje mnoho možností pro téměř dokonalý popis REST API. Je to nejsnazší cesta k vytvoření předlohy API, než napíšete jediný řádek kódu. Zkuste to ručně, zkuste si pomoci editorem VS Code a když už to nepůjde jinak, sáhněte do peněženky a zvažte některý z vizuálních nástrojů.
Školení zaměřená na OAS v České republice zatím nemáme. Kdyby Vás zajímal Design REST API, zvu Vás na mé veřejné školení, které mohu udělat i u Vás ve firmě. Součástí je i povídání o OAS a související procvičování. Na základě dohody je možné v tomto školení věnovat problematice návrhu v OAS i více času.