Generador de clases según definición OpenAPI en ObjectScript
InterSystems IRIS ofrece la posibilidad de crear interfaces REST con el enfoque spec-first, esto es, partiendo de las especificaciones de la API.
Puedes echarle un vistazo a este artículo para más información al respecto : https://es.community.intersystems.com/post/cómo-desarrollar-una-api-rest-con-un-enfoque-spec-first.
Algo muy práctico que tiene este enfoque y la propia OpenAPI, es la definición de los objetos que se van a intercambiar.
El comando do ^%REST
crea las rutas y los métodos asociados, pero sin embargo no crea las definiciones de los objetos.
Este es la salida del comando do ^%REST
para el ejemplo de Petshop:
USER>do ^%REST
REST Command Line Interface (CLI) helps you CREATE or DELETE a REST application.
Enter an application name or (L)ist all REST applications (L): PetShop
REST application not found: PetShop
Do you want to create a new REST application? Y or N (Y): Y
File path or absolute URL of a swagger document.
If no document specified, then create an empty application.
OpenAPI 2.0 swagger: https://petstore.swagger.io/v2/swagger.json
OpenAPI 2.0 swagger document: https://petstore.swagger.io/v2/swagger.json
Confirm operation, Y or N (Y):
-----Creating REST application: PetShop-----
CREATE PetShop.spec
GENERATE PetShop.disp
CREATE PetShop.impl
REST application successfully created.
Create a web application for the REST application? Y or N (Y):
Specify a web application name beginning with a single '/'. Default is /csp/PetShop
Web application name: /csp/petshop
-----Deploying REST application: PetShop-----
Application PetShop deployed to /csp/petshop
Como vemos en el ejemplo, se han generado 3 clases:
- una clase disp (no accesible al usuario).
- una clase impl (que contiene la implementación de la API).
- una clase spec (que contiene la definición de OpenAPI en un bloque XData)
¿Y si además pudiésemos crear un paquete que contenga todas las definiciones de clases incluidas en la especificación?
Eso es lo que vamos a hacer con esta aplicación de OpenExchange disponible con el gestor de paquetes ZPM.
Para instalarlo con zpm:
USER>zpm
zpm: USER>install objectscript-openapi-definition
[objectscript-openapi-definition] Reload START
[objectscript-openapi-definition] Reload SUCCESS
[objectscript-openapi-definition] Module object refreshed.
[objectscript-openapi-definition] Validate START
[objectscript-openapi-definition] Validate SUCCESS
[objectscript-openapi-definition] Compile START
[objectscript-openapi-definition] Compile SUCCESS
[objectscript-openapi-definition] Activate START
[objectscript-openapi-definition] Configure START
[objectscript-openapi-definition] Configure SUCCESS
[objectscript-openapi-definition] Activate SUCCESS
Una vez instalado puedes utilizarlo de la siguiente forma:
zw ##class(Grongier.OpenApi.Definition).Process("PetShop.spec")
Compilation started on 04/06/2020 15:40:49 with qualifiers ''
Compiling 6 classes, using up to 8 worker jobs
Compiling class PetShop.Definition.ApiResponse
Compiling class PetShop.Definition.Category
Compiling class PetShop.Definition.Tag
Compiling class PetShop.Definition.Order
Compiling class PetShop.Definition.Pet
Compiling class PetShop.Definition.User
Compiling routine PetShop.Definition.Tag.1
Compiling routine PetShop.Definition.Category.1
Compiling routine PetShop.Definition.Order.1
Compiling routine PetShop.Definition.ApiResponse.1
Compiling routine PetShop.Definition.User.1
Compiling routine PetShop.Definition.Pet.1
Compilation finished successfully in 0.183s.
Como ves, se han generado las clases incluidas en la especificación OpenAPI.
Las clases generadas, incluyen:
- campos requeridos
- tipos
- valores mínimos/máximos
De esta forma, podrías convertir un cuerpo de un mensaje a un objeto de una de estas clases generadas:
ClassMethod addPet(body As %Stream.Object) As %Stream.Object
{
// Verify payload confirmity against definition
Set tPaylaod = ##class(PetShop.Definition.Pet).%New()
Set tSC = tPaylaod.%JSONImport(body)
If ($$$ISERR(tSC)) {
Do ..%ReportRESTError(500,tSC,1) Quit ""
}
Quit ""
}
Puedes encontrar el código y más ejemplos en este repositorio: https://github.com/grongierisc/objectscript-openapi-definition