Skip to content
This repository has been archived by the owner on Apr 13, 2019. It is now read-only.
Konstantin Sobolev edited this page Apr 28, 2018 · 23 revisions

Intro

Epigraph is a framework for building and consuming services, with the main philosophy is that services should be simple, composable, and decoupled from each other. They should usually describe only a single functional domain. Service APIs should be minimal yet flexible, with clients having a lot of run-time freedom over describing what exactly an operation should do. Services should be glued together using federation layer which connects them into one big graph of data.

Framework has a number features designed to help with these goals:

  • Expressive domain model language. It supports semantic types, multiple inheritance, injections, metadata and custom attributes
  • Entity types that allow fields containing multiple representations of a value. This helps with data federation and better versioning support. Changing a field from a simple type to an entity type is a backward-compatible change
  • Projections as a structured way of defining both implementation and invocation contracts for operations
  • Federation layer automatically providing rich graph APIs on top of small domain-specific services

And of course a usual set of features:

  • Language agnostic
  • Pluggable wire protocols
  • full CRUD support plus custom actions
  • Bulk operations with partial failures support
  • REST-like HTTP interface
  • Asynchronous client bindings

Overview

Following sections give a high level picture of system design.

Deployment

Typical deployment consists of a number of domain-specific services, each providing it's own API. On top of them there is a Federator service which stitches individual services together to provide graph-like API for reads.

/img/comp.svg

Clients can consume services directly, like Client A, or they can talk to the federation layer, like Client B. They can also chose to use federator as a library and configure it to only see a selected subset of services, like Client C does.

Key point here is that services don't have to talk to each other in order to provide rich APIs, they focus on their own business and provide only minimal information about external relations in the form of IDs, URNs or any other link format.

Clients such as UI can get access to the whole graph of objects provided by all of the services via federation layer, which knows how to traverse the links between different kinds of objects. This knowledge is based on the individual services API declarations.

Development

Service development consists of the following steps:

  1. Authoring service schema. Schema describes domain model objects, relationships between them and service APIs
  2. Compiling schema and generating data container classes and service implementation stubs
  3. Implementing the stubs

Clients generate data containers and client bindings from schema.

With federation in the picture everything stays the same, federator merely looks like another service which adds deep read operations to another services.