Introduction

Asbru is an async_graphql Data-oriented Service Mesh generator: it'll generate an async_graphql project from a schema with resolvers, dataloaders, data-transformation. It'll create a Data-oriented service mesh from your schema so you'll just have to describe your microservices with your described schema to have a Data-Oriented Service Mesh like Airbnb's.

It aims to be fully compatible with the Relay GraphQL specification and most of its extensions and offers type safety and high performance thanks to the async-graphql crates.

Warnings

We follow the SemVer, so he Asbru project won't be usable before the 0.1.0 release and won't be stable before the 1.0.0 release.

This book is still a work in progress.

Origin

The whole project comes from an awesome talk and a closed-source project from Airbnb named Viaduct. I suggest you to read it, it's very interesting! The following and the whole project is inspired by this article.

What is a Data-Oriented Service Mesh?

In most entrprise, we have a lot of microservices. It can be thousands to tens of thousands microservices connected together. We have dependencies everywhere between microservices.

<Insérer image qui représente un SOA ici.>

The whole purpose of a Data-Oriented Service Mesh is to create a service, which is a service mesh, which will be able to know where the data is located and will be able to route every request we have to the instances of microservices able to handle them.

We will try to create GraphQL to create a Data-Oriented Service mesh where the whole business structure is represented so services won't have to talk to each other directly but will be able to only talk to this GraphQL endpoint.

You could even modelize your whole public API through an Asbru endpoint.

With this modelisation, the only service which know how to compose data from your services is the Asbru endpoint, so you don't have to manage every dependencies inside your microservices.

Why do this?

I enjoy using GraphQL and Rust, I was very impressed by the work from Sunli on async_graphql, I wanted to play my part with the Rust / GraphQL ecosystem and I saw the incredible article which described Viaduct from Airbnb. It's a closed source project (at least in 2021) and I though it would be awesome to have this kind of project with async_graphql. So I am doing this.

How to contribute?

You can contribute to the project by creating issues, proposing ideas, suggesting ideas, coding things, whatever you want, I'm eager to know what you think of it. If you are looking for a code of conduct to follow, please follow the Rust code of conduct. It's just common sense, and be nice ❤️.

Quickstart

To create a basic schema with Asbru, just use:

asbru \
  --config example/test01/config.toml \
  --schema example/test01/schema.graphql \
  --output example/test01result/

This schema is a schema used to develop Asbru, you can access this generated schema at this address: https://asbru-schema-01.herokuapp.com/graphql.

Feel free to use GraphQL Voyager to explore the generated schema.

Docker

We provide a docker file example to create a docker image from a schema and a config file.

Roadmap

The Asbru Roadmap, no deadlines are indicated because it's an open-source project where I don't get paid to work on it.

0.1.0 Release

The 0.1.0 release aims to provide a working GraphQL Gateway with Queries and Connections. No caching strategy are expected. The whole point for this release is to create a main structure to iterate.

1.0.0 Release

The 1.0.0 Release aims to provide a working Data-Oriented Service Mesh usable from the entreprise to the solo dev prototyping an application.

Configuration

You can configure Asbru with a lot of options to create your GraphQL API.

Services

When you create a Asbru project you have to describe how your data is going to be fetched. There are multiple transports possible.

Your services should be describe inside a config.toml file which will gather your whole project configuration.

Transports

HTTP

An example of a service definition for an HTTP service:

[services]

# Beer API Based on Open Brewery DB
# https://www.openbrewerydb.org/documentation/01-listbreweries
# A Good use case to work with Connection and pagination with the list
# https://api.openbrewerydb.org/breweries
# [services.beers]
# transport = { HTTP = { endpoint = "https://api.openbrewerydb.org/breweries", method = "GET" } }

# Pets store API
# Usefull for test
[services.pets.transport]
type = "HTTP"

[services.pets.transport.info]
endpoint = "https://petstore3.swagger.io/api/v3/"

[services.pets.transport.info.method.petGetById]
route = "pet/{id}"
http_method = "GET"

[services.pets.transport.info.method.placeOrderForAPet]
route = "store/order"
http_method = "POST"
body_args = ["id", "petId", "quantity", "shipDate", "status", "complete"]

Generation

Every service definition won't generate anything until you use a fetch directive associated.

Extensions

/!\ This part is not working right now /!

Inside the configuration file, you can also define which extensions should be used and how. Asbru provides out of the box several extensions implementations to allow you to create a powerfull GraphQL API.

Apollo Studio

Apollo studio is an Apollo Service which allow you to add an observability tool to your GraphQL API.

async-graphql has an extension to create & send your graphql metrics to Apollo Studio: async_graphql_apollo_studio_extension.

Architecture

This chapter will describe how Asbru is working internally to create a working async-graphql project from your schema definitions.

Layered architecture

Asbru will generate a compilable async_graphql project based on an opinniated layered Architecture (c.f. Domain Driven Design p.68).

A layered Architecture is an architecture which divide an application into 3 main sub-parts:

  - The applicative layer
  - The domain layer
  - The infrastructure layer

The whole purpose of this architecture is to be able to modelize your business rules and entities and separate them from the implementation details.

You can change a layer without having to change other layers.

The typical structure of a software built with this architecture is that top layer is able to import sub-layers but sub-layers can't import top-layers.

Applicative layer

The applicative layer will be responsible to modelize your GraphQL schema, it'll represent the whole generated schema and describe how async-graphql should get data when a field is requested.

Domain layer

The domain layer is the core layer of this architecture, it's where your business rules are represented. It means in our case, it's where your internal data representation is represented and it's where we'll store our dataloaders modelisation.

Infrastructure layer

The infrastructure layer will manage every connection to external services, extensions, logging, metrics and monitoring which will be used by the other layers.

Opiniated Implementation

I'm not an expert in Domain Driven Design, so I did my implementation of it, if you want to give feedback about this, do not hesitate to participate within Github. It's an open-source project :-).

Steps

  • First of all, we check if the configuration is correct, the configuration will have multiple elements: extensions, services.
  • Then we parse the whole graphql schema with async-graphql-parser.
  • We iterate over types to create struct & methods
  • It's done

Schema

Asbru is a Schema driven tool: you have to define your schema to generate the corresponding GraphQL api.

Asbru will also generate resolvers based on directives applied to your schema.