ALPS Helfer Library
19. Dezember 2020Hi :).
Der neue von mir entwickelte ALPS Converter macht es möglich eine ALPS Spezifikation (kurz Spec) zu OpenApi, GraphQL oder anderen APIs zu konvertieren.
import { Alps, FormatType } from 'alps-unified-ts';
// geladen von einer YAML File
Alps.unified(Alps.loadYaml('todo-alps.yaml'), { formatType: FormatType.OPENAPI })
Weitere tolle Features meine ALPS unified Library sind:
Das GitHub Projekt wurden mit Projen erstellt. Was die ALPS Api und Projen ist will ich in den nächsten Abschnitten genauer erörtern.
ALPS API
ALPS ist eine Spezifikation zur Beschreibung vom Context eines Services. ALPS kann verwendet werden als Spezifikationinput zum generieren von niedrig abstrahierten Spezifikationen wie OpenApi / Swagger, WSDL, RAML, WADL.
Der ALPS Converter convertiert also eine ALPS Api Spec in niedriger abstrahierten Api Spezifikationen. Ein Beispiel für so eine Konvertierung folgt im nächsten Abschnitt.
ALPS API Spec Beispiel
Das folgende Beispiel ist eine simple TODO ALPS API Spec.
alps:
version: '1.0'
doc:
value: 'Simple Todo list example'
####################################
# metadata
ext:
- type: metadata
name: title
value: simpleTodo
tags: 'oas'
- type: metadata
name: id
value: http://alps.io/profiles/mamund/simpleTodo
tags: 'oas'
- type: metadata
name: root
value: http://api.example.org/todo
tags: 'oas'
descriptor:
# properties
# - these are the data elements
- id: id
type: semantic
text: storage id of todo item
- id: body
type: semantic
text: content of todo item
# groupings
# - these are the storage objects
- id: todoItem
type: group
text: todo item
descriptor:
- href: '#id'
- href: '#body'
# actions
# - these are the operations
- id: todoList
type: safe
rt: todoItem
text: return list of todo items
- id: todoAdd
type: unsafe
rt: todoItem
text: create a new todo item
descriptor:
- href: '#todoItem'
- id: todoRemove
type: idempotent
tags: delete
rt: todoItem
text: remove a single todo item
descriptor:
- href: '#id'
Das Element todoItem besteht aus einer id und einem todo string body . Es sind drei Aktionen definiert todoList zum listen der todo Einträge, todoAdd zum Einfügen neuer todos und todoRemove zum Löschen von todo Einträgen.
Daraus kann der Unified Convertierer diese OpenApi Spezifikation generieren:
openapi: 3.0.1
# *******************************************************************
# generated by "unified" from src/todo-alps.yaml
# date: Wed Nov 25 2020 18:47:05 GMT+0100 (Central European Standard Time)
# http://github.com/mamund/2020-11-unified
# *******************************************************************
info:
title: simpleTodo
description: Simple Todo list example
version: 1.0.0
servers:
- url: 'http://api.example.org/todo'
paths:
/todoList:
get:
summary: 'return list of todo items'
operationId: todoList
responses:
200:
description: todoList
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/todoItem'
/todoAdd:
post:
summary: 'create a new todo item'
operationId: todoAdd
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/todoItem'
responses:
200:
description: add todoAdd
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/todoItem'
/todoRemove/{id}:
delete:
summary: 'remove a single todo item'
operationId: todoRemove
parameters:
- name: id
in: path
description: id of todoRemove
required: true
schema:
type: string
responses:
204:
description: delete todoRemove
components:
schemas:
todoItem:
description: todo item
type: object
properties:
id:
type: string
example: 4572
body:
type: string
example: jn1ov7axj4kv560d0921xf
Oder auch dieses GraphQL Schema:
# *******************************************************************
# generated by "unified"
# date: Fri Dec 11 2020 16:51:00 GMT+0100 (Central European Standard Time)
# http://github.com/mamund/2020-11-unified
# *******************************************************************
type todoItem {
id: String!
body: String!
}
type Query {
todoList: [todoItem]
}
type Mutation {
todoAdd(todoItem: String!): todoItem
todoRemove(id: String!): todoItem
}
schema {
query: Query,
mutation: Mutation
}
Projen
Projen erlaubt eine ausgeklügelte Verwaltung von Projektkonfiguration durch Code. Mit nur wenigen Zeilen TypeScript Code kann ein gesamtes Repository konfiguriert werden. Hierfür ein Beispiel:
const { JsiiProject } = require('projen');
const project = new JsiiProject({
name: 'alps-unified-ts',
authorAddress: 'damadden88@googlemail.com',
authorName: 'Martin Mueller',
});
project.synth();
Diese wenigen Zeilen erzeugen alle GitHub Projektfiles die das Herz begehrt. Darunter die package.json, .gitignore, tsconfig.json und noch viele viele mehr.
Wirklich richtig cool ist das Projen auch mit GitHub Workflows kommt die z.B. neue Versionen publishen können nach Registries wie NPM oder PYPI.
Ich habe das Projen Framework lieben gelernt, da es tolle Abstraktion und Vorgabe für ein Setup von Projekten ist. Ich lege dir ans Herz Projen mal einen Versuch zu geben und sehr bald wirst du die Schönheit dieses Frameworks selber erleben.
ALPS Library in Action
Hier möchte ich nun kurz meine neue ALPS Unified Library vorstellen. Das TypeScript package kann so
import { Alps, FormatType } from 'alps-unified-ts';
// geladen von einer YAML File
Alps.unified(Alps.loadYaml('./spec/todo-alps.yaml'), { formatType: FormatType.OPENAPI })
// oder direct per TypeScript Object
Alps.unified(Alps.spec({
alps: {
version: '1.0',
doc: {
value: 'Simple Todo list example',
},
...
}
});
Die Alps.unified(...) Function gibt immer einen String zurück. Je nach formType beinhaltet der zurückgegebene String das gewünsche Format. In unserem Beispiel ist das FormatType.OPENAPI welches OpenApi in YAML ist. Würde man nun gerne OpenAPI in JSON zurückhaben wollen, ginge auch FormatType.OPENAPI_JSON. Für die Wiedergabe des Graph QL Schemas müsste man FormatType.DSL verwenden.
In Python kann die Library so benutzt werden:
import alps_unified_ts as alps
alps_def = alps.AlpsDef(
version='1.0',
descriptor=[alps.DescriptorDef(id="id", type="semantic", text="sotrage id of todo item")],
doc=alps.DocDef(
value="Simple Todo list example"),
ext=[
alps.ExtDef(
name="root",
tags="oas",
type="metadata",
value="http://api.example.org/todo"),
alps.ExtDef(
name="title",
tags="oas",
type="metadata",
value="simpleTodo")])
alps_converted = alps.Alps.unified(alps_document=alps.Alps.spec(alps=alps_def), format_type=alps.FormatType.OPENAPI)
Die Verwendung in Java und .NET sollte ähnlich aussehen.
In meinem vorherigen Blogpost ALPS kombiniert mit CDK erkläre ich wie aus einer ALPS Spec wahlweise ein AWS Api Gateway oder AWS Appsync mit dem ALPS Todo Beispiel und der ALPS unified library erzeugen werden kann.
Zusammenfassung
Eine Library mit Projen zu bauen war super fun! Ich habe damit eine neue, verbesserte Version von der alps unified library gebaut. Diese kommt jetzt mit supper coolen neuen Funktionen die ich hier vorgestellt habe.
Achja eine Info noch. Falls euch auch das ALPS Thema interessiert, mit der ALPS Community veranstalten wir regelmäßig Community Treffen online. Dort trefft ihr spannende Leute auß aller Welt. Kommt gerne mal vorbei :) .
An die tollen Leser dieses Artikels sei gesagt, dass Feedback jeglicher Art gerne gesehen ist. In Zukunft werde ich versuchen hier eine Diskussionsfunktion einzubauen. Bis dahin sendet mir doch bitte direkten Feedback über meine Sozial Media accounts wie Twitter oder FaceBook. Vielen Dank :).
Ich liebe es an Content Management Open Source Projekte zu arbeiten. Vieles kannst du bereits frei nutzen auf www.github.com/mmuller88 . Wenn du meine dortige Arbeit sowie meine Blog Posts toll findest, denke doch bitte darüber nach, mich zu unterstützen und ein Patreon zu werden: