MDSL (Micro-)Service Contracts Generator

Introduction and Motivation

The Microservices Domain Specific Language (MDSL) is a DSL to specify (micro-)service contracts and data representations realizing the API Description pattern from Microservice API Patterns (MAP).

With our MDSL generator you can automatically produce (micro-)service contracts out of your strategic DDD context map written in CML. The generator creates the contracts according to the following mapping, which reflects our proposal how we would derive (micro-)services from models based on strategic DDD. The generator aims for providing assistance regarding how your system can be implemented in an (micro-)service-oriented architecture.

Generator Mapping

CML Input MDSL Output Description
Upstream Bounded Contexts from upstream-downstream relationships Service Specification (API description) We create one service specification for each upstream Bounded Context of your Context Map.
Exposed Aggregates Endpoint Every exposed Aggregate of your upstream Bounded Context results in one endpoint.
Public methods/operations of the aggregate root entity or of Services. Operation Your exposed Aggregates should contain methods/operations, either on the aggregate root entity or in Services. For every method/operation in those objects we generate an operation in MDSL.
Parameters & return values of methods/operations Base types or data type specifications if possible If you use primitive data types in CML, they are mapped to the base types of MDSL. If you refer to objects (such as entities) in CML, we produce a corresponding parameter tree. Types which are not further declared are mapped to abstract, unspecified elements (P).
Upstream Bounded Contexts from upstream-downstream relationships API provider For the upstream Bounded Context we also generate an API provider.
Downstream Bounded Contexts from upstream-downstream relationships API client Downstream Bounded Contexts are mapped to corresponding API clients.

Data Type Mapping

The base/primitive types are mapped as follows:

CML type MDSL type
String V<string>
int or Integer V<int>
long or Long V<long>
double or Double V<double>
boolean V<bool>
Blob V<blob>
Date V<string> (no date available in MDSL)
Note: Types in CML are case sensitive. For example: If you write "string" instead of "String", you create a new abstract data type instead of using the primitive type "String".

If you declare a method with multiple parameters or refer to an object (such as entity or value object) in CML, we generate a corresponding parameter tree. For example the following entity would be mapped to the parameter tree below:

CML input:

Entity Address {
  String street
  String lockbox nullable
  int postalCode
  String city
}

MDSL data type result:

data type Address { "street":V<string>, "lockbox":V<string>?, "postalCode":V<int>, "city":V<string> }

All abstract data types which are not base types and not specified in CML (no references to objects) will produce an abstract, unspecified element in MDSL, as the following example illustrates:

data type JustAnUnspecifiedParameterType P

Example

An example MDSL API description looks as follows:

// Generated from DDD Context Map 'Insurance-Example_Context-Map.cml' at 21.10.2019 17:48:52 CEST.
API description CustomerManagementContextAPI
usage context PUBLIC_API for BACKEND_INTEGRATION

data type Address { "street":V<string>, "postalCode":V<int>, "city":V<string> }
data type AddressId P
data type changeCustomerParameter { "firstname":V<string>, "lastname":V<string> }

endpoint type CustomersAggregate
  serves as INFORMATION_HOLDER_RESOURCE
  exposes
    operation createAddress
      with responsibility "Creates new address for customer"
      expecting
        payload Address
      delivering
        payload AddressId
    operation changeCustomer
      with responsibility "Changes existing customer address"
      expecting
        payload changeCustomerParameter
      delivering
        payload V<bool>

// Generated from DDD upstream Bounded Context 'CustomerManagementContext' implementing OPEN_HOST_SERVICE (OHS) and PUBLISHED_LANGUAGE (PL).
API provider CustomerManagementContextProvider
  // The customer management context is responsible for managing all the data of the insurance companies customers.
  offers CustomersAggregate
  at endpoint location "http://localhost:8001"
    via protocol "RESTfulHTTP"

// Generated from DDD upstream Bounded Context 'CustomerManagementContext' implementing OPEN_HOST_SERVICE (OHS) and PUBLISHED_LANGUAGE (PL).
API client PolicyManagementContextClient
  // This bounded context manages the contracts and policies of the customers.
  consumes CustomersAggregate
API client CustomerSelfServiceContextClient
  // This context represents a web application which allows the customer to login and change basic data records like the address.
  consumes CustomersAggregate

IPA

Note: This example has been generated from our insurance example which you can find in our examples repository.

Known Limitations

We are aware of the following generator issues, which may lead to MDSL results which do not compile:

  • If you use reserved keywords of the MDSL language as Aggregate name, Bounded Context name, operation name or data type name in CML, the result may not be valid MDSL.
    • Workaround: Do not use MDSL keywords within your CML model.

User Guide

You can generate MDSL (micro-)service contracts from your CML model as follows.

With a right-click to your CML-file in Eclipse you will find a Context Mapper context menu. With the action MDSL: Generate Service Contracts you generate the contracts for all upstreams in your Context Map:

MDSL Generator

Note that the Context Mapper menu entry is also available within the context menu uf the CML editor. (right-click anywhere in the editor)

All MDSL files will be generated into the src-gen folder of your project:

MDSL Generator Result

Note: The MDSL Eclipse plugin is not yet available for download (update site). At the moment you can open the *.mdsl files with a text editor only (no syntax highlighting and editor support available yet).

Protected Regions

After you generated an MDSL contract you can add protected regions for data types, endpoint types, API providers, and API clients if you want to modify parts of the contract and protect them from being overwritten. The following example shows the corresponding comments needed to begin and end the four different protected regions:

// Generated from DDD Context Map 'Insurance-Example_Context-Map.cml' at 21.10.2019 17:48:52 CEST.
API description CustomerManagementContextAPI
usage context PUBLIC_API for BACKEND_INTEGRATION

// ** BEGIN PROTECTED REGION for data types

// ** END PROTECTED REGION for data types

data type Address { "street":V<string>, "postalCode":V<int>, "city":V<string> }
data type AddressId P
data type changeCustomerParameter { "firstname":V<string>, "lastname":V<string> }

// ** BEGIN PROTECTED REGION for endpoint types

// ** END PROTECTED REGION for endpoint types

endpoint type CustomersAggregate
  serves as INFORMATION_HOLDER_RESOURCE
  exposes
    operation createAddress
      with responsibility "Creates new address for customer"
      expecting
        payload Address
      delivering
        payload AddressId
    operation changeCustomer
      with responsibility "Changes existing customer address"
      expecting
        payload changeCustomerParameter
      delivering
        payload V<bool>

// ** BEGIN PROTECTED REGION for API providers

// ** END PROTECTED REGION for API providers

// Generated from DDD upstream Bounded Context 'CustomerManagementContext' implementing OPEN_HOST_SERVICE (OHS) and PUBLISHED_LANGUAGE (PL).
API provider CustomerManagementContextProvider
  // The customer management context is responsible for managing all the data of the insurance companies customers.
  offers CustomersAggregate
  at endpoint location "http://localhost:8001"
    via protocol "RESTfulHTTP"

// ** BEGIN PROTECTED REGION for API clients

// ** END PROTECTED REGION for API clients

// Generated from DDD downstream Bounded Context 'PolicyManagementContext' implementing CONFORMIST (CF).
API client PolicyManagementContextClient
  // This bounded context manages the contracts and policies of the customers.
  consumes CustomersAggregate
API client CustomerSelfServiceContextClient
  // This context represents a web application which allows the customer to login and change basic data records like the address.
  consumes CustomersAggregate

IPA

The protected regions allow you to move data types, endpoints, API providers, and API clients into its corresponding protected region so that they are not overwritten at re-generation. Thus, you can call the MDSL generator on the same file again and all objects within a protected region will not be changed.

For example, you can move a set of data types into the corresponding protected region if you changed the data types manually after generation and want to protect them:

// Generated from DDD Context Map 'Insurance-Example_Context-Map.cml' at 21.10.2019 17:48:52 CEST.
API description CustomerManagementContextAPI
usage context PUBLIC_API for BACKEND_INTEGRATION

// ** BEGIN PROTECTED REGION for data types

data type Address { "street":V<string>, "postalCode":V<int>, "city":V<string>, "manuallyChangedThisDataType":V<string> }

// ** END PROTECTED REGION for data types

data type AddressId P
data type changeCustomerParameter { "firstname":V<string>, "lastname":V<string> }

// removed the rest here to save space ...

IPA

MDSL Support

The current version of our MDSL generator is compatible with the MDSL version 1.0.2. For further questions regarding MDSL please visit the website https://socadk.github.io/MDSL or contact Olaf Zimmermann.