Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added asynchronous API guidelines content #71

Merged
merged 17 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The API Guidelines are split into two main parts:
* [General Guidelines](general-guidelines/general-guidelines.md)
* API type-specific Guidelines
* [REST APIs Guidelines](rest-api-guidelines/rest.md)
* [Asynchronous APIs Guidelines](asynchronous-api-guidelines/asyncapi.md)
* [Asynchronous APIs Guidelines](asynchronous-api-guidelines/index.md)

The general guidelines section discusses the core principles relevant to any kind of API. The API type-specific section further defines the guidelines specific to a given architectural style or API technique \(such as REST, Kafka or GraphQL APIs\).

Expand Down
34 changes: 32 additions & 2 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,35 @@

## Asynchronous API Guidelines

* [Introduction](asynchronous-api-guidelines/asyncapi.md)

* [Introduction to guidelines](asynchronous-api-guidelines/01_introduction/a_introduction.md)
* Basic Concepts
* [Event Driven Architectures](asynchronous-api-guidelines/01_introduction/b_basic_concepts_edas.md)
* [Basic terminology](asynchronous-api-guidelines/01_introduction/c_basic_concepts_terminology.md)
* [Events](asynchronous-api-guidelines/01_introduction/d_basic_concepts_events.md)
* Asynchronous API Guidelines
* [Contract](asynchronous-api-guidelines/02_asynchronous_api_guidelines/a_contract.md)
* [API First](asynchronous-api-guidelines/02_asynchronous_api_guidelines/b_api_first.md)
* [Immutability](asynchronous-api-guidelines/02_asynchronous_api_guidelines/c_immutability.md)
* [Common Data Types](asynchronous-api-guidelines/02_asynchronous_api_guidelines/d_data_types.md)
* [Automatic Schema Registration](asynchronous-api-guidelines/02_asynchronous_api_guidelines/e_schema_registration.md)
* [Schema Data Evolution](asynchronous-api-guidelines/02_asynchronous_api_guidelines/f_schema_data_evolution.md)
* [Key/Value format](asynchronous-api-guidelines/02_asynchronous_api_guidelines/g_key_value_format.md)
* [Message Headers](asynchronous-api-guidelines/02_asynchronous_api_guidelines/h_message_headers.md)
* [Naming Conventions](asynchronous-api-guidelines/02_asynchronous_api_guidelines/i_naming_conventions.md)
* [Protocols](asynchronous-api-guidelines/02_asynchronous_api_guidelines/j_protocols.md)
* [Security](asynchronous-api-guidelines/02_asynchronous_api_guidelines/k_security.md)
* AsyncAPI specs for Kafka
* [Introduction](asynchronous-api-guidelines/03_asyncapi_kafka_specs/a_introduction.md)
* [AsyncAPI version](asynchronous-api-guidelines/03_asyncapi_kafka_specs/b_asyncapi_version.md)
* [Internal vs Public specs](asynchronous-api-guidelines/03_asyncapi_kafka_specs/c_internal_public_specs.md)
* [Spec granularity](asynchronous-api-guidelines/03_asyncapi_kafka_specs/d_spec_granularity.md)
* [Meaningful descriptions](asynchronous-api-guidelines/03_asyncapi_kafka_specs/e_meaningful_descriptions.md)
* [Self-contained specs](asynchronous-api-guidelines/03_asyncapi_kafka_specs/f_self_contained_specs.md)
* [Contact Information](asynchronous-api-guidelines/03_asyncapi_kafka_specs/g_contact_information.md)
* [AsyncAPI ID](asynchronous-api-guidelines/03_asyncapi_kafka_specs/h_asyncapi_id.md)
* [Servers](asynchronous-api-guidelines/03_asyncapi_kafka_specs/i_servers.md)
* [Channels](asynchronous-api-guidelines/03_asyncapi_kafka_specs/j_channels.md)
* [Schemas](asynchronous-api-guidelines/03_asyncapi_kafka_specs/k_schemas.md)
* [Security Schemes](asynchronous-api-guidelines/03_asyncapi_kafka_specs/l_security_schemes.md)
* [External Docs](asynchronous-api-guidelines/03_asyncapi_kafka_specs/m_external_docs.md)
* [Tooling](asynchronous-api-guidelines/03_asyncapi_kafka_specs/n_tooling.md)
Binary file added assets/eda_overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/eda_problem_statement_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/eda_problem_statement_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sr_backward_compatibility.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sr_forward_compat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sr_full_compat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions asynchronous-api-guidelines/01_introduction/a_introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# adidas Asynchronous API guidelines

## Introduction

### About guidelines

In the scope of a company, organization or team, the document known as guidelines is a set of best practices or hints provided by a group of subject matter experts in that particular technology. The most important aspects of it:

- Help to create a standardized way of completing specific tasks, making outcome more predictable and alike
- Help to identify do's and dont's with regards to a specific technology or tool
- Help to avoid gotchas or problems related with company specifics
- Gather the knowledge of several Subject Matter Experts and prevent others for falling in frequent caveats or mistakes

**Note** In any case, the content in the guidelines should be taken as recommendations, not something that needs to be done in a mandatory way.








Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# adidas Asynchronous API guidelines

## Basic concepts about asynchronous APIs

### Event-driven architectures

#### What is an event-driven architecture

Event-Driven Architectures (EDAs) are a paradigm that promotes the production, consumption and reaction to events.

This architectural pattern may be applied by the design and implementation of applications and systems that transmit events amongst loosely coupled software components and services.

An event-driven system typically consists of event emitters (or agents), event consumers (or sinks), and event channels.

- Producers (or publishers) are responsible for detecting, gathering and transferring events
- Are not aware of consumers
- Are not aware of how the events are consumed
- Consumers (or subscribers) react to the events as soon as they are produced
- The reaction can be self-contained or it can be a composition of processes or components
- Event channels are conduits in which events are transmited from emitters to consumers

**Note** Producer and Consumer role is not exclusive. In other words, the same client or application can be producer and consumer at the same time.


In most cases, EDAs are broker-centric, as seen in the diagram below.

![EDA overview](../../assets/eda_overview.png)

#### Problem statement

Typically, the architectural landscape of a big company grows in complexity and as a result of that it is possible to end up with a bunch of direct connections between a myriad of different components or modules.

![Typical architecture diagram](../../assets/eda_problem_statement_1.png)

By using streaming patterns, it is possible to get a much cleaner architecture

![EDA architecture diagram](../../assets/eda_problem_statement_2.png)


It is important to take into account that EDAs are not a silver bullet, and there are situations in which this kind of architectures might not fit very well.

One example is systems that heavily rely on transactional operations... of course it might be possible to use EDA but most probably the complexity of the resulting architecture would be too high.

Also, it is important to note that it is possible to mix request-driven and event-driven protocols in the same system. For example,

- Online services that interact directly with a user fits better into the synchronous communication but they also can generate events into Kafka.
- On the other hand, offline services (billing, fulfillment, etc) are typically built purely with events.

#### Kafka as the heart of EDAs

There are several technologies to implement event-driven architectures, but this section is going to focus on the predominant technology on this subject : Apache Kafka.

**Apache Kafka** can be considered as a Streaming Platform which relies on the several concepts:

- Super high-performance, scalable, highly-available cluster of brokers
- Availability
- Replication of partitions across different brokers
- Scalability
- Partitions
- Ability to rebalance partitions across consumers automatically when adding/removing them
- Performance
- Partitioned, replayable log (collection of messages appended sequentially to a file)
- Data copied directly from disk buffer to network buffer (zero copy) without even being imported to the JVM
- Extreme throughput by using the concept of consumer group and
- Security
- Secure encrypted connections using TLS client certificates
- Multi-tenant management through quotas/acls
- Client APIs on different programming languages : Go, Scala, Python, REST, JAVA, ...
- Stream processing APIs (currently Kafka Streams and ksqlDB)
- Ecosystem of connectors to pull/push data from/to Kafka
- Clean-up processes for storage optimization
- Retention periods
- Compacted topics
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# adidas Asynchronous API guidelines

## Basic concepts about asynchronous APIs

### Basic terminology

#### Events

An event is both a fact and a notification, something that already happened in the real world.

- No expectation on any future action
- Includes information about a status change that just happened
- Travels in one direction and it never expects a response (fire and forget)
- Very useful when...
- Loose coupling is important
- When the same piece of information is used by several services
- When data needs to be replicated across application

A message in general is any interaction between an emitter and a receiver to exchange information. This implies that any event can be considered a messages but not the other way around.

#### Commands

A command is a special type of message which represents just an action, something that will change the state of a given system.

- Typically synchronous
- There is a clear expectation about a state change that needs to take place in the future
- When returning a response indicate completion
- Optionally they can include a result in the response
- Very common to see them in orchestration components

#### Query

It is a special type of message which represents a request to look something up.

- They are always free of side effects (leaves the system unchanged)
- They always require a response (with the requested data)

#### Coupling

The term coupling can be understood as the impact that a change in one component will have on other components. In the end, it is related to the amount of things that a given component shares with others. The more is shared, the more tight is the coupling.

**Note** A tighter coupling is not necessarily a bad thing, it depends on the situation. It will be necessary to assess the tradeoff between provide as much information as possible and to avoid having to change several components as a result of something changing in other component.

The coupling of a single component is actually a function of these factors:

- Information exposed (Interface surface area)
- Number of users
- Operational stability and performance
- Frequency of change

Messaging helps bulding loosely coupled services because it moves pure data from a highly coupled location (the source) and puts it into a loosely coupled location (the subscriber).

Any operations that need to be performed on the data are done in each subscriber and never at the source. This way, messaging technologies (like Kafka) take most of the operational issues off the table.

All business systems in larger organizations need a base level of essential data coupling. In other words, functional couplings are optional, but core data couplings are essential.

#### Bounded context

A bounded context is a small group of services that share the same domain model, are usually deployed together and collaborate closely.

It is possible to put an analogy here with a hierarchic organization inside a company :

- Different departments are loosely coupled
- Inside departments there will be a lot more interactions across services and the coupling will be tighter

One of the big ideas of Domain-Driven Design (DDD) was to create boundaries around areas of a business domain and model them separately. So within the same bounded context the domain model is shared and everything is available for everyone there.

However, different bounded contexts don't share the same model and if they need to interact they will do it through more restricted interfaces.

#### Stream processing

It can be understood as the capability of processing data directly as it is produced or received (hence, in real-time or near to real-time).
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# adidas Asynchronous API guidelines

## Basic concepts about asynchronous APIs

### Using events in an EDA

There are several ways to use events in a EDA:

- Events as notifications
- Events to replicate data


#### Events as notifications

When a system uses events as notifications it becomes a pluggable system. The producers have no knowledge about the consumers and they don't really care about them, instead every consumer can decide if it is interested in the information included in the event.

This way, the number of consumers can be increased (or reduced) without changing anything on the producer side.

This pluggability becomes increasily important as systems get more complex.

#### Events to replicate data

When events are used to replicate data across services, they include all the necessary information for the target system to keep it locally so that it can be queried with no external interactions.

This is usually called event-carried state transfer which in the end is a form of data integration.

The benefits are similar to the ones implied by the usage of a cache system

- Better isolation and autonomy, as the data stays under service's control
- Faster data access, as the data is local (particularly important when combining data from different services in different geographies)
- Offline data availability
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# adidas Asynchronous API guidelines

## Asynchronous API guidelines

### Contract

The definition of an asynchronous API **MUST** represent a contract between API owners and the stakeholders.

That contract **MUST** contain enough information to use the API (servers, URIs, credentials, contact information, etc) and to identify which kind of information is being exchanged there.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# adidas Asynchronous API guidelines

## Asynchronous API guidelines

### API First

Asynchronous APIs **SHOULD** use the API First principle :

- The API designs **SHOULD** involve all relevant stakeholders (developers, consumers, ...) to ensure that final design fulfil requirements from different perspectives
- The resulting API specification will be the source of truth rather than the API implementation
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# adidas Asynchronous API guidelines

## Asynchronous API guidelines

### Immutability

After agreement with the stakeholders the contract **MUST** be published in order to do it immutable. Changes to the API related to the data model, **MUST** be published in a schema registry.

Schema registry acts as a central location for storing and accessing the schemas of all published APIs.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# adidas Asynchronous API guidelines

## Asynchronous API guidelines

### Common data types

The API types **MUST** adhere to the formats defined below:

| Data type | Standard | Example |
| --------- | -------- | ------- |
| Date and Time | [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) | 2017-06-21T14:07:17Z (Always use UTC) |
| Date | [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) | 2017-06-21 |
| Duration | [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) | P3Y6M4DT12H30M5S |
| Time interval | [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) | 2007-03-01T13:00:00Z/2008-05-11T15:30:00Z |
| Timestamps | [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) | 2017-01-01T12:00:00Z |
| Language Codes | [ISO 639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) | en <-> English |
| Country Code | [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) | DE <-> Germany |
| Currency | [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) | EUR <-> Euro |
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# adidas Asynchronous API guidelines

## Asynchronous API guidelines

### Automatic schema registration

Applications **MUST NOT** enable automatic registration of schemas because FDP's operational model for the Schema Registry relies on GitOps (every operation is done through GIT PRs + automated pipelines)
Loading