Programación con API de Java, Parte 1: OpenAPI y Swagger

Mientras tomaba su café, el desarrollo de la aplicación Java cambió, nuevamente .

En un mundo impulsado por cambios e innovación rápidos, es irónico que las API estén regresando. Al igual que el equivalente de codificación del sistema de metro de la ciudad de Nueva York en la era de los automóviles autónomos, las API son tecnología antigua, antigua pero indispensable. Lo interesante es cómo esta arquitectura de TI invisible y cotidiana está siendo rediseñada y utilizada en las tendencias tecnológicas actuales.

Si bien las API están en todas partes, se han vuelto especialmente prominentes en su encarnación remota como servicios RESTful, que son la columna vertebral de las implementaciones en la nube. Los servicios en la nube son API públicas , que se caracterizan por estructuras publicadas y terminales de cara al público. Las aplicaciones basadas en la nube también tienen una tendencia hacia los microservicios , que son implementaciones independientes pero relacionadas. Todos estos factores aumentan la importancia de las API.

En este tutorial de dos partes, aprenderá a poner las API de Java en el centro de su proceso de diseño y desarrollo, desde el concepto hasta la codificación. La parte 1 comienza con una descripción general y le presenta OpenAPI, también conocido como Swagger. En la Parte 2, aprenderá cómo usar las definiciones de API de Swagger para desarrollar una aplicación Spring Web MVC con una interfaz Angular 2.

¿Qué es una API de Java?

Las API son tan comunes en el desarrollo de software que a veces se asume que los programadores simplemente saben lo que son. En lugar de confiar en la ósmosis, tomemos un minuto para analizar lo que queremos decir cuando hablamos de API.

En general, podemos decir que las API establecen y gestionan los límites entre sistemas.

Primero, API significa "interfaz de programación de aplicaciones". La función de una API es especificar cómo interactúan los componentes de software. Si está familiarizado con la programación orientada a objetos, conoce las API en su encarnación como las interfaces y clases utilizadas para obtener acceso a las características subyacentes del lenguaje, o como la cara pública de las bibliotecas de terceros y las capacidades del sistema operativo.

En general, podemos decir que las API establecen y administran los límites entre los sistemas, como se ve en la Figura 1.

Matthew Tyson

Entonces, ¿dónde nos deja eso con el desarrollo impulsado por API?

API de Java para computación en la nube, microservicios y REST

La programación con API pasa a primer plano con la API web moderna: una API expuesta a la red (NEA) , donde el límite entre los sistemas está "sobre el cable". Estos límites ya son fundamentales para las aplicaciones web, que son el punto de contacto común entre los clientes front-end y los servidores back-end. La revolución de la nube ha aumentado exponencialmente la importancia de las API de Java.

Cualquier actividad de programación que requiera consumir servicios en la nube (que son básicamente API públicas) y deconstruir sistemas en implementaciones más pequeñas, independientes pero relacionadas (también conocidas como microservicios), depende en gran medida de las API. Las API expuestas a la red son simplemente más universales, más fáciles de obtener y más fáciles de modificar y ampliar que las API tradicionales. La tendencia arquitectónica actual es capitalizar estas características.

Los microservicios y las API públicas se desarrollan a partir de las raíces de la arquitectura orientada a servicios (SOA) y el software como servicio (SaaS). Aunque SOA ha sido una tendencia durante muchos años, la adopción generalizada se ha visto obstaculizada por la complejidad y los gastos generales de SOA. La industria se ha decidido por las API RESTful como el estándar de facto, que proporciona la estructura y la convención suficientes con más flexibilidad en el mundo real. Con REST como telón de fondo, podemos crear definiciones de API formales que conservan la legibilidad humana. Los desarrolladores crean herramientas en torno a esas definiciones.

En general, REST es una convención para mapear recursos a rutas HTTP y sus acciones asociadas. Probablemente los haya visto como métodos HTTP GET y POST. La clave es utilizar HTTP en sí mismo como estándar, y superponer mapeos convencionales encima para lograr previsibilidad.

Uso de API de Java en diseño

Puede ver la importancia de las API, pero ¿cómo las utilizaría para su beneficio?

El uso de definiciones de API de Java para impulsar el proceso de diseño y desarrollo es una forma eficaz de estructurar su pensamiento sobre los sistemas de TI. Al utilizar las definiciones de la API de Java desde el principio del ciclo de vida del desarrollo de software (recopilación de conceptos y requisitos), creará un valioso artefacto técnico que será útil hasta la implementación, así como para el mantenimiento continuo.

Consideremos cómo las definiciones de la API de Java unen las etapas conceptual y de implementación del desarrollo.

API descriptivas vs prescriptivas

Es útil hacer una distinción entre API descriptivas y prescriptivas. Una API descriptiva describe la forma en que funciona realmente el código, mientras que una API prescriptiva describe cómo debería funcionar el código .

Ambos estilos son útiles y ambos se mejoran enormemente mediante el uso de un formato estándar estructurado para la definición de API. Como regla general, usar la API para impulsar la creación de código es un uso prescriptivo, mientras que usar el código para generar la definición de la API de Java es un uso descriptivo.

Recopilación de requisitos con API de Java

En el espectro desde el concepto hasta la implementación, la recopilación de requisitos está muy por encima del lado del concepto. Pero incluso en la etapa conceptual del desarrollo de aplicaciones, podemos empezar a pensar en términos de API.

Supongamos que su sistema en diseño se ocupa de bicicletas de montaña: construcción, piezas, etc. Como desarrollador orientado a objetos, comenzaría hablando con las partes interesadas sobre los requisitos. Bastante rápido después de eso, estarías pensando en una BikePartclase abstracta .

A continuación, pensaría en la aplicación web que administraría los distintos objetos de piezas de bicicleta. Pronto, llegaría a los requisitos comunes para administrar esas piezas de bicicleta. A continuación, se muestra una instantánea de la fase de requisitos de la documentación para una aplicación de piezas de bicicleta:

  • La aplicación debe poder crear un tipo de pieza de bicicleta (palanca de cambios, freno, etc.).
  • Un usuario autorizado debe poder listar, crear y activar un tipo de pieza.
  • Un usuario no autorizado debe poder enumerar los tipos de piezas activas y ver listas de instancias de tipos de piezas individuales en el sistema.

Ya puede ver cómo van tomando forma los esquemas de los servicios. Con eventuales API en mente, puede comenzar a esbozar esos servicios. Como ejemplo, aquí hay una lista parcial de los servicios RESTful CRUD para tipos de piezas de bicicleta:

  • Crear tipo de pieza de bicicleta: PUT /part-type/
  • Actualizar el tipo de pieza de bicicleta: POST /part-type/
  • Listar tipos de piezas: GET /part-type/
  • Obtenga detalles del tipo de pieza: GET /part-type/:id

Observe cómo los servicios CRUD comienzan a insinuar la forma de varios límites de servicio. Si está compilando en un estilo de microservicios, ya puede ver tres microservicios que emergen del diseño:

  • Un servicio de repuestos para bicicletas
  • Un servicio de bicicleta tipo pieza
  • Un servicio de autenticación / autorización

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.

A medida que desarrolle la aplicación, también verá el valor de usar API para capturar la negociación de ida y vuelta entre el desarrollo y el negocio. El uso de herramientas API acelerará la aplicación y la documentación de los cambios de código.

Las especificaciones más granulares y la codificación real pueden requerir más detalles que la definición concisa en el Listado 1. Además, los sistemas más grandes y complejos podrían merecer capacidades que se escalen, como las referencias de documentos. El Listado 2 muestra un ejemplo más desarrollado de la API BikePart.

Listado 2. Agregar detalles a la definición de API BikePart

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