View on GitHub

MDSL

A domain-specific language to specify (micro-)service contracts and their data representations (realizing the API Description pattern from MAP)

Service Endpoint Contracts in MDSL

Usage

Concepts

The contract syntax is inspired by the domain model in/for MAP

serviceSpecification: 
	'API' 'description' name=ID
	('usage' 'context' visibility=visibility 
	    'for' direction+=directionList)?
	types+=dataContract*
	contracts+=endpointContract+
	providers+=provider*
	clients+=client*
	gateways+=gateway*
	('IPA')? ;

endpointContract:
	'endpoint' 'type' name=ID 
	('version' svi=semanticVersioningIdentifier)? 
	('serves' 'as' primaryRole=ResourceRole 
	    ('and' otherRoles+=ResourceRole)* 'role'?)? 
	('identified' 'by' pathParameters=elementStructure)? 
	('exposes' ops+=operation+)? ;

operation:
	'operation' name=ID
	('version' svi=semanticVersioningIdentifier)?
	('with' 'responsibility' respos=operationResponsibility)? 
	'expecting' requestMessage=dataTransferRepresentation
	('delivering' responseMessage=dataTransferRepresentation
		('reporting' reportData=statusReport)? // optional
	)? ;

dataTransferRepresentation:
	('headers' headers=elementStructure)? 
	'payload' payload=elementStructure
	('structured' 'as' ts=typeSystem)? ;

The notation used above is the grammar language of Xtext (which close to that of antlr4).

Example

The following exemplary API specification compiles against the MDSL grammar sketched above:

API description SampleCustomerManagementAPI
usage context PUBLIC_API for FRONTEND_INTEGRATION 

endpoint type CustomerManagementContract 
  version 1.0.0 
  serves as INFORMATION_HOLDER_RESOURCE
  exposes 
  	operation lookupSingleCustomer 
	  with responsibility RETRIEVAL_OPERATION 
	  expecting 
		payload ID<string> 
	  delivering  
		payload {"customerId":ID<int>,
		          "name":V,
		          "address"} 
				
  	operation lookupCustomerDirectory
	  with responsibility RETRIEVAL_OPERATION
	  expecting 
		payload <<Request_Bundle>> "customerId":ID<int>+ 
	  delivering
		payload
		  "customerRecord": { 
			"cid":ID!, // ! mandatory, exactly one
			"nameTuple":("firstname":V, "lastname":V), 
			"addressTuple":(
			  "street":V<string>, 
			  "poBox":V?, // optional
			  "zipCode":V, 
			  "city":V)+,
			"segment":("REGULAR":V|"VIP":V) // choice 
		}* // zero or more

The described API supports one endpoint type CustomerManagementContract that exposes two operations to retrieve some customer data in a Customer Relationship Management (CRM) scenario (lookupSingleCustomer, lookupCustomerDirectory) . Some parts of the data contract are fully specified, whereas others are still incomplete. MAPs are used to annotate endpoint, operation, and one representation element (INFORMATION_HOLDER_RESOURCE, RETRIEVAL_OPERATION).1 Foundation patterns from MAP comment on the usage scenario for the described API (here: PUBLIC_API for FRONTEND_INTEGRATION); this is optional.

The first operation lookupSingleCustomer requires the API client to send an ID in the request message to be able to return the corresponding customer record. Response messages are optional in MDSL, while request messages are mandatory.

The response message format lists three atomic parameters. The second operation lookupCustomerDirectory works with multiple customer ids so that multiple records can be returned in one response, which implements the Request Bundle pattern in MAP. This is indicated with the <<Request_Bundle>> stereotype. These pattern stereotypes merely serve as markers; tools such as code generators can use them to fine-tune their output.

Note: If an operation does not expect or deliver any payload, this can be expressed with the help of the empty/null type V<void>. This type should only be used for this purpose.

For more explanations of the message structures, see data contracts (schemas).

Reporting (e.g., of Errors)

See quick reference for the time being.

Technology Mappings

RESTful HTTP (a.k.a. HTTP resource APIs)

Endpoints correspond to resources (with the mapping not being straightforward due to concepts such as URI templates and path parameters in HTTP). Operations correspond to HTTP verbs or methods (with additional constraints being imposed by the architectural style and nest practices for REST).

WSDL

MDSL endpoints map to port types in WSDL; operations (not surprisingly) to operations. API providers are pendants to ports in WSDL, API clients are service consumers.

Jolie

The service contract grammar can easily be mapped to the glossary of Jolie terms. For instance, endpoint types in MDSL correspond to interfaces in Jolie:

Jolie MDSL/MAP Comments
Operation Operation n/a
Interface Endpoint type n/a
tbd API (multiple endpoint types) n/a
Port (inbound) API provider n/a
Port (outbound) API client n/a
(Micro-)Service (Micro-)Service exposes one or more APIs with one or more operations
Conversation Conversation to be checked
Service definition (service implementation) n/a
Service network tbd n/a
Cell and related concepts not in scope n/a

Other integration technologies

MSDL service contracts can also be mapped to gRPC, GraphQL, and Avro in a straightforward manner. Stay tuned!

Data contracts (schemas) and optional runtime language concepts.

Quick reference.

Back to MDSL homepage.

Copyright: Olaf Zimmermann, 2019. All rights reserved.

  1. The notion of API roles and responsibilities as well as the term Information Holder have their roots in Responsibility-Driven Design (RDD).