View on GitHub

Microservice DSL (MDSL)

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

HomePrimerEndpoint TypesBindingsTutorialTools

MDSL Transformations

Goal- and Service-Oriented Analysis and Design

Use Cases for the Transformations

Go here or here to gain a basic understanding of the MDSL concepts and language constructs so that you can benefit from the transformations described on this reference page.

A number of transformations are available, most of which are implemented as plugin quick fixes.

Note: The modified MDSL might not always validate after a transformation (for instance, when operation names are not unique). This is deliberate; it is possible to correct such issues with subsequent refactorings (such as Rename Element) or basic manual edit operations.

Note: If certain preconditions are not met, some quick fixes will fail. The “Error Log” view in Eclipse will have an entry in that case that reports the problem.

Analysis and Orchestration Steps

The available analysis transformations (early steps, story level):

MDSL element Transformation (Quick Fix) Resulting MDSL Comments (Preconditions, Variants)
Scenario Derive application flow from scenario Basic flow, single step (one event, one command) Can be a requirement, an integration scenario, a test case
Scenario Add endpoint type supporting this scenario Endpoint type (with operations for stories) CRUD stories receive special attention
Scenario story Add operation to endpoint type supporting scenario Operation for action, role stereotyped Endpoint may or may not exist

Flows optionally can serve as analysis and design bridge en route to endpoint types and their technology-specific refinements:

MDSL element Transformation (Quick Fix) Resulting MDSL Comments (Preconditions, Variants)
Flow step Add a command invocation step (triggered by event) Let event trigger a new command in new step Supports incremental modeling
Flow step Add a domain event production step (emitting event) Let the new step emit a ‘CommandDone’ event Branching/joining supported in language but not in transformations
Flow Derive endpoint type from application flow Endpoint added to name of new endpoint, which receives a flow start event Operations can be added later
Command (invocation) in a flow step Add an operation to endpoint type that realizes this command MAP decorator: STATE_TRANSITION_OPERATION transitions from ... to ... added to operation
Flow step emitting an event Derive event processor operation from flow step MAP decorator: EVENT_PROCESSOR emitting event added to operation

API Design Steps

This table lists and specifies the endpoint-level design transformations (intermediate steps):

MDSL element Transformation (Quick Fix) Resulting MDSL Comments (Preconditions, Variants)
Endpoint type Turn into Processing Resource CRUD operations added Turn into Information Holder Resource also available
Endpoint type Add operations common/typical for this role stereotype CRUD operations added for Processing Resource Retrieval operations added for Information Holder Resource; Data Transfer Resource and Link Lookup Resource also supported
Operation Add error/status report Adds basic example of a report To be refined manually
Operation Add security policy Adds basic example of a policy To be refined manually
Endpoint type Add compensating operation Business-level undo (saga support) Must choose an existing operation in same endpoint
Event in endpoint type Introduce event management Adds suited operations to endpoint Requires a receives event reference to be present
Endpoint type Add HTTP binding Adds a provider with location information and a single HTTP resource binding Particularly useful if endpoint type cannot be mapped to single resource (due to number and nature of operations)
Provider Split HTTP binding Moves all operations that cause OpenAPI mapping conflicts to new resource Must have an HTTP binding (with default resource), might have to be executed multiple times to resolve all mapping conflicts

An additional Move Operationrefactoring is available as a menu entry, not as a quick fix. And AsyncMDSL can be generated from core MDSL via a menu entry too.

This table lists and specifies transformations related to data types:

MDSL element Transformation (Quick Fix) Resulting MDSL Comments (Preconditions, Variants)
Data type placeholder P or id only "anonymous" Replace with atomic string parameter "anonymous":D<string> Can serve as input to subsequent transformations
Incomplete type "someType":D Add string as type "someType":D<string> Also available for other basic types (bool, int, raw, long, double)
Atomic parameter list ("a":D , "b":D<int>) Replace atomic parameter list with parameter tree {"a":D , "b":D<int>} Trees are more flexible
Atomic parameter "a":ID<int> Wrap atomic parameter with parameter tree "aWrapper":{"a":ID<int>} Can not be applied recursively yet
Atomic parameter "a":MD<int> Include atomic parameter in key-value map "aKeyValueMap":{"key":ID<string> , "a":MD<int>} Example of a commonly used data structure
Any type in message payload Extract data type definition data type definition and type reference To support reuse of specification elements
Operation with parameter tree request Introduce Wish List Set parameter added, decorated with marked with <<Wish_List>> Transformation only works for inlined types
Operation working with parameter trees Introduce Request Bundle Parameter tree turned into set and marked with <<Request_Bundle>> Also available for response message (must be parameter tree); transformation only works for inlined types
Operation working with parameter trees Introduce offset-based pagination Atomic parameters added, response decorated with marked with <<Pagination>> Both request and response message must be parameter trees; transformation only works for inlined types

Note: Only few of these refactorings are also supported in the CLI (for instance, Add Pagination and Add endpoint type supporting this scenario).

Example

Applying the above transformations, you can go from:

API description SoadDemo

scenario SampleIntegrationScenario
  story ElaborateStory
   when "something has happened" //precondition
   a "customer and/or integrator" // role
   wants to "doSomething" // business activity 
   yielding "a result" // outcome
   so that "both actors are satisfied and profit is made" // goal 
    
  story ShortStory
    a API client
    wants to CRUD "SomeBusinessObject" 
    // CRUD is short for Create, Read, Update, Delete  

to this MDSL specification:

API description SoadDemo
data type SomeBusinessObjectDTO {"someBusinessObject":D}
data type SampleIntegrationScenarioRealizationEndpointDTO "sampleIntegrationScenarioRealizationEndpoint":D<string>

event type something_has_happened
event type CRUDSomeBusinessObjectTrigger
event type SampleIntegrationScenarioFlowInitiated "eventDetails":MD<string>
event type CRUDSomeBusinessObjectCompleted

command type doSomething
command type CRUDSomeBusinessObject

endpoint type SampleIntegrationScenarioRealizationEndpoint supports scenario SampleIntegrationScenario
serves as INFORMATION_HOLDER_RESOURCE
exposes
  operation doSomething expecting payload {"dataTransferObject":D} delivering payload "doSomethingResponseBody":D<string>
  operation createSomeBusinessObject with responsibility STATE_CREATION_OPERATION expecting payload SomeBusinessObjectDTO delivering payload "resourceId":ID<string>
  operation readSomeBusinessObject with responsibility RETRIEVAL_OPERATION expecting payload "queryFilter":MD<string> delivering payload "resultSet":SomeBusinessObjectDTO*
  operation updateSomeBusinessObject with responsibility STATE_TRANSITION_OPERATION expecting payload "changeRequest":SomeBusinessObjectDTO delivering payload "updateResult":SomeBusinessObjectDTO
  operation deleteSomeBusinessObject with responsibility STATE_DELETION_OPERATION expecting payload "resourceId":ID<string> delivering payload "successFlag":D<bool>
  operation findAll with responsibility RETRIEVAL_OPERATION expecting payload "queryFilter":MD<string> delivering payload "resultSet":SampleIntegrationScenarioRealizationEndpointDTO*
  operation findById with responsibility RETRIEVAL_OPERATION expecting payload "resourceId":ID<string> delivering payload SampleIntegrationScenarioRealizationEndpointDTO

endpoint type SampleIntegrationScenarioFlowEndpoint supports flow SampleIntegrationScenarioFlow serves as PROCESSING_RESOURCE
exposes
operation doSomething with responsibility STATE_TRANSITION_OPERATION 
  expecting payload "doSomethingRequestBodyWrapper":{"doSomethingRequestBody":D<string>, <<Wish_List>> "desiredElements":MD<string>*} 
  delivering payload "doSomethingResponseBody" 
  transitions from "doSomethingTriggered" to "doSomethingExecuted"
operation cRUDSomeBusinessObject with responsibility EVENT_PROCESSOR 
  expecting payload "cRUDSomeBusinessObjectRequestBody" 
  delivering payload "cRUDSomeBusinessObjectResponseBody" 
  emitting event CRUDSomeBusinessObjectCompleted
receives event SampleIntegrationScenarioFlowInitiated

API provider SampleIntegrationScenarioRealizationEndpointProvider offers SampleIntegrationScenarioRealizationEndpoint at endpoint location "http://localhost:8080"
via protocol HTTP binding
resource Home at "/Home"
  operation doSomething to POST all elements realized as BODY parameters
  operation createSomeBusinessObject to PUT all elements realized as BODY parameters
  operation readSomeBusinessObject to GET all elements realized as QUERY parameters
resource Home_deleteSomeBusinessObject at "/{resourceId}"
  operation deleteSomeBusinessObject to DELETE element "resourceId" realized as PATH parameter
resource Resource2 at "/Resource2"
  operation updateSomeBusinessObject to POST all elements realized as BODY parameters
  operation findAll to GET all elements realized as QUERY parameters
resource Resource3 at "/Resource3"
  operation findById to GET all elements realized as QUERY parameters

flow SampleIntegrationScenarioFlow realizes SampleIntegrationScenario
  event something_has_happened triggers command doSomething
  event CRUDSomeBusinessObjectTrigger triggers command CRUDSomeBusinessObject
  command CRUDSomeBusinessObject emits event CRUDSomeBusinessObjectCompleted

without any programming or MDSL editing. Several transformation steps were applied to the input story.

Exercise: Can you identify the involved transformations? Hint: apply the ones listed in the tables above; watch the validation warnings (and information and errors) while doing so.

You can find the answer in the HTML source of this page.

Generating Technology-Specific Contracts

Once the MDSL contract is reasonably complete, the generators can be used to turn it into OpenAPI etc. (final steps). The OpenAPI generated from the above MDSL is here.

Question: How long did the entire journey take you? Compare with code-first or contract first with plain OpenAPI (or other platform IDL) editing (i.e., no transformation and pattern support).

Site Navigation

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