View on GitHub

Microservice DSL (MDSL)

A Domain-Specific Language (DSL) to specify (micro-)service contracts, their data representations and API endpoints.

HomeEndpoint TypeData TypesProvider and ClientTutorialCheat SheetTools

Protocol Bindings for HTTP, gRPC, Jolie, Java

MDSL by design abstracts from and generalizes concepts in other API contract languages. This is rather straightforward for most of them (and has been done before). For HTTP resource APIs, additional concepts and an intermediate step are required because MDSL endpoints do not map to resources and their URIs one-to-one (what about dynamic addressing as promoted by URI templates/path parameters? how to map complex request payloads of retrieval operations, HTTP GET and request bodies do not go well together?). The HTTP Protocol Binding of MDSL realizes this intermediate step in a flexible way.

Overview

Let us start with the following endpoint type (and then show all available bindings in this example):

API description ProductManagement version "v0.0.1"

data type ProductDescription P /* defined incompletely */
data type Money {"currency":D, "amount":D<int>} /* defined incompletely, but a bit more precisely */
data type ErrorReport {"rootCause":D<string>, "correctiveAction":D<string>}

endpoint type ProductManagementService
exposes 
  operation define
    expecting payload "productDescription": ProductDescription
    delivering payload "successAck": D<bool>
      // technology-neutral error reporting (to be bound to OAS/HTTP, gRPC, Java, Jolie):
      reporting error DuplicateEntry D<string>
    // technology-neutral security policy (to be bound to protocols and platforms):
    protected by policy BasicAuthentication "UserIdPassword": {"userId":ID<string>, "password":MD<string>}
  operation updatePrice /* optional: "in REQUEST_REPLY conversation" */
    expecting payload "price": Money  
    // delivering payload D<void>
    // not delivering any payload, just a transport-level status code

HTTP Protocol Binding

HTTP handles addressing, request and response parameters, errors, and security concerns in certain ways (for good reasons). The protocol design deviates from than of most interface definition languages and “RPC-ish” communication protocols. To generate OpenAPI and, later on, server-side stubs and client-side proxies from MDSL specifications, some of the required information can therefore always be derived from the abstract endpoint types. A primary example is the mapping of MDSL operations to HTTP verbs/methods such as GET, POST, PUT etc.

The additional information can be specified in a provider-level HTTP binding:

API provider ProductManagementWebServiceProvider
  offers ProductManagementService
  at endpoint location "http://www.tbc.io:80/path/subpath"
  via protocol HTTP  
    binding 
     resource PMSResource at "/products/{productId}" // PATH parameter (implicit)
      operation define to POST 
        all elements realized as BODY parameters
        report DuplicateEntry realized as 412 with "DuplicateEntry"
        policy BasicAuthentication realized as BASIC_AUTHENTICATION
        accepts "application/json"// defined at https://www.iana.org/assignments/media-types/media-types.xhtml
        replies "application/vnd.custom-mediatype-for-productDTO-v1" // custom media type 
      
      operation updatePrice to PATCH at "/products/{productId}/price"
        element "currency" realized as QUERY parameter
        element "amount" realized as QUERY parameter

The information in the binding refers to and refines the operation- and message level specification (abstract endpoint type level:)

Note: The protocol bindings (“adapters”) stand at an intermediate level of elaboration and validation. Grammar, linter, and generator support are rather stable, but might still change in future versions of MDSL and MDSL Tools.

gRPC Protocol Buffers Binding

gRPC is easier to map than HTTP. At present, the grammar only foresees one additional construct:

enum StreamingOption:
	client | server | bidirectional // if not present, "unary" is assumed
;

See the gRPC documentation for explanations.

API provider ProductManagementGRPCServiceProvider
  offers ProductManagementService
  at endpoint location "tbd"
  via protocol gRPC
    // no need for bindings here, but still demoing it: 
    binding
     operation define to "define" as server stream
     operation updatePrice as bidirectional stream

Jolie Binding

There is no such binding at present; in the future we might support concepts such as namespace (and pass this information on to the jolie2wsdl tool that comes with Jolie).

Local Java Binding

A binding is defined that maps operations to methods and representation elements to parameters (both optional), and allows contract and binding designers to specify a Java package:

API provider ProductManagementJavaServiceProvider
  offers ProductManagementService
  at endpoint location "n/a" 
  via protocol Java
    // no need for operation bindings here, but still demoing them: 
    binding 
     package "co.something.model.ProductActor"
     operation define to "define"
        element productDescription realized as int type
     operation updatePrice to "updatePrice"
        element money realized as boolean type

In the current release, only the package name is used.

Other Bindings

An enum in the grammar defines some more commonly used protocols (no detailed bindings for these technologies have been defined yet):

OtherBinding:
    soap='SOAP_HTTP' | avro='Avro_RPC' | thrift='Thrift' | amqp='AMQP' | jms='JMS_ActiveMQ' | stomp='STOMP' | kafka='Kafka' | mqtt='MQTT' | other=STRING 
;

The “other” part of this grammar rule makes it possible to define "AnyOtherProtocol" (without expecting the existing tools to be able to do anything specific with this information).

Site Navigation

Copyright: Olaf Zimmermann, 2018-2022. All rights reserved. See license information.