ALPS Helfer Library

19th December 2020

Hi :).

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:

  • automatische versioniertes Releasing nach NPM, PyPi, Maven und Nuget (für .NET)
  • Typensupport

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:

Werde ein Patreon!

Share