Programmieren mit Java-APIs, Teil 1: OpenAPI und Swagger

Während Sie Ihren Kaffee bekamen, änderte sich die Java-Anwendungsentwicklung erneut .

In einer Welt, die von schnellen Veränderungen und Innovationen geprägt ist, ist es ironisch, dass APIs ein Comeback erleben. Wie die Codierung Äquivalent von New York City U-Bahn - System im Zeitalter der autonomen Autos, APIs sind alt Tech --ancient aber unverzichtbar. Interessant ist, wie diese unsichtbare, alltägliche IT-Architektur neu konzipiert und in aktuellen Technologietrends eingesetzt wird.

Während APIs überall sind, sind sie in ihrer Remote-Inkarnation als RESTful-Services, die das Rückgrat von Cloud-Bereitstellungen bilden, besonders bekannt geworden. Cloud-Dienste sind öffentliche APIs , die sich durch öffentlich zugängliche Endpunkte und veröffentlichte Strukturen auszeichnen. Cloud-basierte Apps tendieren auch zu Microservices , bei denen es sich um unabhängige, aber verwandte Bereitstellungen handelt. All diese Faktoren erhöhen die Bekanntheit von APIs.

In diesem zweiteiligen Tutorial erfahren Sie, wie Sie Java-APIs vom Konzept bis zur Codierung in den Mittelpunkt Ihres Design- und Entwicklungsprozesses stellen. Teil 1 beginnt mit einer Übersicht und führt Sie in OpenAPI ein, auch bekannt als Swagger. In Teil 2 erfahren Sie, wie Sie mithilfe der API-Definitionen von Swagger eine Spring Web MVC-App mit einem Angular 2-Frontend entwickeln.

Was ist eine Java-API?

APIs sind in der Softwareentwicklung so verbreitet, dass manchmal angenommen wird, dass Programmierer einfach wissen, was sie sind. Anstatt sich auf Osmose zu verlassen, nehmen wir uns eine Minute Zeit, um zu entpacken, was wir meinen, wenn wir über APIs sprechen.

Im Allgemeinen können wir sagen, dass APIs die Grenzen zwischen Systemen festlegen und verwalten.

Erstens steht API für "Application Programming Interface". Die Rolle einer API besteht darin, anzugeben, wie Softwarekomponenten interagieren. Wenn Sie mit objektorientierter Programmierung vertraut sind, kennen Sie APIs in ihrer Inkarnation als Schnittstellen und Klassen, die für den Zugriff auf zugrunde liegende Funktionen der Sprache verwendet werden, oder als öffentliches Gesicht von Bibliotheken und Betriebssystemfunktionen von Drittanbietern.

Im Allgemeinen können wir sagen, dass APIs die Grenzen zwischen Systemen festlegen und verwalten, wie in Abbildung 1 dargestellt.

Matthew Tyson

Wo bleibt uns also die API-gesteuerte Entwicklung?

Java-APIs für Cloud Computing, Microservices und REST

Das Programmieren mit APIs tritt bei der modernen Web-API in den Vordergrund: einer netzwerkbasierten API (NEA) , bei der die Grenze zwischen Systemen "über das Kabel" liegt. Diese Grenzen sind bereits von zentraler Bedeutung für Web-Apps, die der gemeinsame Kontaktpunkt zwischen Front-End-Clients und Back-End-Servern sind. Die Cloud-Revolution hat die Bedeutung von Java-APIs exponentiell erhöht.

Jede Programmieraktivität, bei der Cloud-Dienste (im Grunde genommen öffentliche APIs) verwendet und Systeme in kleinere, unabhängige, aber verwandte Bereitstellungen (auch als Microservices bezeichnet) dekonstruiert werden müssen, hängen stark von APIs ab. Netzwerkexponierte APIs sind einfach universeller, leichter zu erhalten und leichter zu modifizieren und zu erweitern als herkömmliche APIs. Der aktuelle architektonische Trend besteht darin, diese Merkmale zu nutzen.

Microservices und öffentliche APIs basieren auf den Wurzeln der serviceorientierten Architektur (SOA) und der Software-as-a-Service (SaaS). Obwohl SOA seit vielen Jahren ein Trend ist, wurde die breite Akzeptanz durch die Komplexität und den Overhead von SOA behindert. Die Branche hat sich für RESTful-APIs als De-facto-Standard entschieden und bietet gerade genug Struktur und Konvention mit mehr Flexibilität in der Praxis. Mit REST als Hintergrund können wir formale API-Definitionen erstellen, die die Lesbarkeit des Menschen gewährleisten. Entwickler erstellen Tools für diese Definitionen.

Im Allgemeinen ist REST eine Konvention zum Zuordnen von Ressourcen zu HTTP-Pfaden und den zugehörigen Aktionen. Sie haben diese wahrscheinlich als HTTP-GET- und POST-Methoden gesehen. Entscheidend ist, HTTP selbst als Standard zu verwenden und herkömmliche Zuordnungen zur Vorhersagbarkeit darüber zu legen.

Verwenden von Java-APIs im Design

Sie können die Bedeutung von APIs erkennen, aber wie würden Sie sie zu Ihrem Vorteil nutzen?

Die Verwendung von Java-API-Definitionen zur Steuerung des Entwurfs- und Entwicklungsprozesses ist eine effiziente Methode, um Ihr Denken über IT-Systeme zu strukturieren. Durch die Verwendung von Java-API-Definitionen von Beginn des Softwareentwicklungslebenszyklus (Konzept- und Anforderungserfassung) erstellen Sie ein wertvolles technisches Artefakt, das bis zur Bereitstellung sowie für die laufende Wartung nützlich ist.

Betrachten wir, wie Java-API-Definitionen die konzeptionellen und Implementierungsphasen der Entwicklung überbrücken.

Beschreibende vs präskriptive APIs

Es ist hilfreich, zwischen beschreibenden und vorschreibenden APIs zu unterscheiden. Eine beschreibende API beschreibt die Art und Weise der Code tatsächlich funktioniert, während eine normativ API beschreibt , wie der Code sollte funktionieren.

Beide Stile sind nützlich und werden durch die Verwendung eines strukturierten Standardformats für die API-Definition erheblich verbessert. Als Faustregel gilt, dass die Verwendung der API zur Steuerung der Codeerstellung eine vorgeschriebene Verwendung ist, während die Verwendung des Codes zur Ausgabe der Java-API-Definition eine beschreibende Verwendung ist.

Sammeln von Anforderungen mit Java-APIs

Im Bereich von der Konzeption bis zur Implementierung ist das Sammeln von Anforderungen auf der Konzeptseite weit vorbei. Aber auch in der konzeptionellen Phase der App-Entwicklung können wir anfangen, in APIs zu denken.

Angenommen, Ihr System-in-Design befasst sich mit Mountainbikes - Konstruktion, Teile usw. Als objektorientierter Entwickler sollten Sie zunächst mit den Stakeholdern über die Anforderungen sprechen. Ziemlich schnell danach würden Sie über eine abstrakte BikePartKlasse nachdenken .

Als Nächstes würden Sie die Webanwendung durchdenken, mit der die verschiedenen Objekte für Fahrradteile verwaltet werden. Bald würden Sie zu gemeinsamen Anforderungen für die Verwaltung dieser Fahrradteile gelangen. Hier ist eine Momentaufnahme der Anforderungsphase der Dokumentation für eine Fahrradteile-App:

  • Die Anwendung muss in der Lage sein, eine Art Fahrradteil (Schalthebel, Bremse usw.) zu erstellen.
  • Ein autorisierter Benutzer muss in der Lage sein, einen Teiletyp aufzulisten, zu erstellen und zu aktivieren.
  • Ein nicht autorisierter Benutzer muss in der Lage sein, aktive Teiletypen aufzulisten und Listen einzelner Instanzen von Teiletypen im System anzuzeigen.

Sie können bereits sehen, wie die Umrisse von Diensten Gestalt annehmen. Unter Berücksichtigung eventueller APIs können Sie mit dem Skizzieren dieser Dienste beginnen. Als Beispiel finden Sie hier eine unvollständige Auflistung der RESTful CRUD-Dienste für Fahrradteiletypen:

  • Fahrradteiletyp erstellen: PUT /part-type/
  • Fahrradteiletyp aktualisieren: POST /part-type/
  • Teiletypen auflisten: GET /part-type/
  • Details zum Teiletyp abrufen: GET /part-type/:id

Beachten Sie, wie die CRUD-Dienste beginnen, auf die Form verschiedener Dienstgrenzen hinzuweisen. Wenn Sie in einem Microservices-Stil erstellen, sehen Sie bereits drei Microservices, die aus dem Design hervorgehen:

  • Ein Fahrradteilservice
  • Ein Fahrradteil-Service
  • Ein Authentifizierungs- / Autorisierungsdienst

Because I think of APIs as boundaries of related entities, I consider the microservices from this list to be API surfaces. Together, they offer a big-picture view of the application architecture. Details of the services themselves are also described in a fashion that you will use for the technical specification, which is the next phase of the software development lifecycle.

Technical specification with Java APIs

If you've included the API focus as part of requirements gathering, then you already have a good framework for technical specification. The next stage is selecting the technology stack you will use to implement the specification.

With so much focus on building RESTful APIs, developers have an embarrassment of riches when it comes to implementation. Regardless of the stack you choose, fleshing out the API even further at this stage will increase your understanding of the app's architectural needs. Options might include a VM (virtual machine) to host the application, a database capable of managing the volume and type of data you're serving, and a cloud platform in the case of IaaS or PaaS deployment.

You can use the API to drive "downward" toward schemas (or document structures n NoSQL), or "upward" toward UI elements. As you develop the API specification, you will likely notice an interplay between these concerns. This is all good and part of the process. The API becomes a central, living place to capture these changes.

Another concern to keep in mind is which public APIs your system will expose. Give extra thought and care to these. Along with assisting in the development effort, public APIs serve as the published contract that external systems use to interface with yours.

Public cloud APIs

In general, APIs define the contract of a software system, providing a known and stable interface against which to program other systems. Specifically, a public cloud API is a public contract with other organizations and programmers building systems. Examples are the GitHub and Facebook APIs.

Documenting the Java API

At this stage, you will want to start capturing your APIs in formal syntax. I've listed a few prominent API standards in Table 1.

Comparing API formats

 
Name Summary Stars on GitHub URL
OpenAPI JSON and YML Supported API Standard descended from the Swagger project, includes variety of tools in the Swagger ecosystem. ~6,500 //github.com/OAI/OpenAPI-Specification
RAML YML based spec supported mainly by MuleSoft ~3,000 //github.com/raml-org/raml-spec
API BluePrint An API design language using MarkDown-like syntax ~5,500 //github.com/apiaryio/api-blueprint/

Virtually any format you choose for documenting your API should be okay. Just look for a format that is structured, has a formal spec and good tooling around it, and looks like it will be actively maintained long term. Both RAML and OpenAPI fit that bill. Another neat project is API Blueprint, which uses markdown syntax. For examples in this article we're going to use OpenAPI and Swagger.

OpenAPI and Swagger

OpenAPI is a JSON format for describing REST-based APIs. Swagger started as OpenAPI, but has evolved into a set of tools around the OpenAPI format. The two technologies complement each other well.

Introducing OpenAPI

OpenAPI is currently the most common choice for creating RESTful definitions. A compelling alternative is RAML (RESTful API Markup Language), which is based on YAML. Personally, I've found the tooling in Swagger (especially the visual designer) more polished and error-free than in RAML.

OpenAPI uses JSON syntax, which is familiar to most developers. If you'd rather not strain your eyes parsing JSON, there are UIs to make working with it easier. Part 2 introduces UIs for RESTful definitions.

Listing 1 is a sample of OpenAPI's JSON syntax.

Listing 1. OpenAPI definition for a simple 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" } } } } } } } 

This definition is so concise it is practically Spartan, which is fine for now. There's plenty of room to increase the detail and complexity of the API definition going forward. I'll show you a more detailed iteration of this definition shortly.

Coding from the Java API

Requirements gathering is done and the basic app has been spec'd out, which means you're ready for the fun part---coding! Having a formal Java API definition gives you some distinct advantages. For one thing, you know what endpoints the back-end and front-end developers need to create and code against, respectively. Even if you are a team of one, you'll quickly see the value of an API-driven approach when you begin coding.

Während Sie die Anwendung erstellen, werden Sie auch den Wert der Verwendung von APIs erkennen, um die Hin- und Her-Verhandlungen zwischen Entwicklung und Geschäft zu erfassen. Die Verwendung von API-Tools beschleunigt das Anwenden und Dokumentieren von Codeänderungen.

Detailliertere Spezifikationen und tatsächliche Codierung erfordern möglicherweise mehr Details als die knappe Definition in Listing 1. Darüber hinaus können größere und komplexere Systeme skalierbare Funktionen wie Dokumentreferenzen verdienen. Listing 2 zeigt ein ausführlicheres Beispiel für die BikePart-API.

Listing 2. Hinzufügen von Details zur BikePart-API-Definition

 "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" } } } }