diff --git a/README.md b/README.md index d9d5851..4278112 100644 --- a/README.md +++ b/README.md @@ -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/index.md) + * [Asynchronous APIs Guidelines](asynchronous-api-guidelines/asyncapi.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\). diff --git a/SUMMARY.md b/SUMMARY.md index 1d36dfb..ca86068 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -66,35 +66,5 @@ ## Asynchronous API Guidelines -* [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) \ No newline at end of file +* [Introduction](asynchronous-api-guidelines/asyncapi.md) + diff --git a/assets/eda_overview.png b/assets/eda_overview.png deleted file mode 100644 index 1fdfbc0..0000000 Binary files a/assets/eda_overview.png and /dev/null differ diff --git a/assets/eda_problem_statement_1.png b/assets/eda_problem_statement_1.png deleted file mode 100644 index 4093dd8..0000000 Binary files a/assets/eda_problem_statement_1.png and /dev/null differ diff --git a/assets/eda_problem_statement_2.png b/assets/eda_problem_statement_2.png deleted file mode 100644 index b7ce90c..0000000 Binary files a/assets/eda_problem_statement_2.png and /dev/null differ diff --git a/assets/sr_backward_compatibility.png b/assets/sr_backward_compatibility.png deleted file mode 100644 index 17547da..0000000 Binary files a/assets/sr_backward_compatibility.png and /dev/null differ diff --git a/assets/sr_forward_compat.png b/assets/sr_forward_compat.png deleted file mode 100644 index 8139077..0000000 Binary files a/assets/sr_forward_compat.png and /dev/null differ diff --git a/assets/sr_full_compat.png b/assets/sr_full_compat.png deleted file mode 100644 index effb691..0000000 Binary files a/assets/sr_full_compat.png and /dev/null differ diff --git a/asynchronous-api-guidelines/01_introduction/a_introduction.md b/asynchronous-api-guidelines/01_introduction/a_introduction.md deleted file mode 100644 index 17947f6..0000000 --- a/asynchronous-api-guidelines/01_introduction/a_introduction.md +++ /dev/null @@ -1,22 +0,0 @@ -# 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. - - - - - - - - diff --git a/asynchronous-api-guidelines/01_introduction/b_basic_concepts_edas.md b/asynchronous-api-guidelines/01_introduction/b_basic_concepts_edas.md deleted file mode 100644 index ff15fee..0000000 --- a/asynchronous-api-guidelines/01_introduction/b_basic_concepts_edas.md +++ /dev/null @@ -1,73 +0,0 @@ -# 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 \ No newline at end of file diff --git a/asynchronous-api-guidelines/01_introduction/c_basic_concepts_terminology.md b/asynchronous-api-guidelines/01_introduction/c_basic_concepts_terminology.md deleted file mode 100644 index e75afb0..0000000 --- a/asynchronous-api-guidelines/01_introduction/c_basic_concepts_terminology.md +++ /dev/null @@ -1,72 +0,0 @@ -# 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). \ No newline at end of file diff --git a/asynchronous-api-guidelines/01_introduction/d_basic_concepts_events.md b/asynchronous-api-guidelines/01_introduction/d_basic_concepts_events.md deleted file mode 100644 index 1088591..0000000 --- a/asynchronous-api-guidelines/01_introduction/d_basic_concepts_events.md +++ /dev/null @@ -1,31 +0,0 @@ -# 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 diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/a_contract.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/a_contract.md deleted file mode 100644 index f923242..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/a_contract.md +++ /dev/null @@ -1,9 +0,0 @@ -# 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. \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/b_api_first.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/b_api_first.md deleted file mode 100644 index db5cd1e..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/b_api_first.md +++ /dev/null @@ -1,10 +0,0 @@ -# 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 \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/c_immutability.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/c_immutability.md deleted file mode 100644 index 02f3220..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/c_immutability.md +++ /dev/null @@ -1,9 +0,0 @@ -# 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. \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/d_data_types.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/d_data_types.md deleted file mode 100644 index 4285461..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/d_data_types.md +++ /dev/null @@ -1,18 +0,0 @@ -# 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 | \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/e_schema_registration.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/e_schema_registration.md deleted file mode 100644 index a75ae25..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/e_schema_registration.md +++ /dev/null @@ -1,7 +0,0 @@ -# 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) \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/f_schema_data_evolution.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/f_schema_data_evolution.md deleted file mode 100644 index 8878564..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/f_schema_data_evolution.md +++ /dev/null @@ -1,102 +0,0 @@ -# adidas Asynchronous API guidelines - -## Asynchronous API guidelines - -### Schemas and data evolution - -All asynchronous APIs **SHOULD** leverage Schema Registry to ensure consistency across consumers/producers with regards to message structure and ensuring compatibility across different versions. - -The default compatibility mode in Schema Registry is FULL_TRANSITIVE. This is the more restrictive compatibility mode, but others are also available. More on this on the subsection below. - - #### Compatibility modes - -Once a given schema is defined, it is unavoidable that the schema evolves with time. Everytime this happens, downstream consumers need to be able to handle data with both old and new schemas seamlessly. - -Each new schema version is validated according to the configuration before being created as a new version. Namely, it is checked against the configured compatibility types (see below). - -**Important** The mere fact of enabling Schema Registry is not enough to ensure that there are no compatibility issues in a given integration. The right compatibility mode needs also to be selected and enforced. - -As a summary, the available compatibility types are listed below: - -| Mode | Description | -|------|-------------| -|BACKWARD|new schema versions are backward compatible with older versions| -|BACKWARD_TRANSITIVE|backward compatibility across all schema versions, not just the latest one.| -|FORWARD|new schema versions are compatible with older consumer versions| -|FORWARD_TRANSITIVE|forward compatibility across all schema versions.| -|FULL|both backward and forward compatibility with the latest schema version| -|FULL_TRANSITIVE|both backward and forward compatibility with all schema versions| -|NONE|schema compatibility checks are disabled| - -#### Backward compatibility - -There are two variants here: - -- BACKWARD - Consumers using a new version (X) of a schema can read data produced by the previous version (X - 1) -- BACKWARD_TRANSITIVE - Consumers using a new version (X) of a schema can read data produced by any previous version (X - 1, X - 2, ....) - -The operations that preserve backward compatibility are: - -- Delete fields - - Consumers with the newer version will just ignore the non-existing fields -- Add optional fields (with default values) - - Consumers will set the default value for the missing fields in their schema version - -![Backward compatibility](../../assets/sr_backward_compatibility.png) - -#### Forward compatibility - -Also two variants here: - -- FORWARD - Consumers with previous version of the schema (X - 1) can read data produced by Producers with a new schema version (X) -- FORWARD_TRANSITIVE - Consumers with any previous version of the schema (X - 1, X - 2, ...) can read data produced by Producers with a new schema version (X) - -The operations that preserve forward compatibility are: - -- Adding a new field - - Consumers will ignore the fields that are not defined in their schema version -- Delete optional fields (with default values) - - Consumers will use the default value for the missing fields defined in their schema version - -![Forward compatibility](../../assets/sr_forward_compat.png) - -#### Full compatibility - -This is a combination of both compatibility types (backward and forward). It also has 2 variants: - -- FULL - Backward and forward compatible between schemas X and X - 1. -- FULL_TRANSITIVE - Backward and forward compatible between schemas X and all previous ones (X - 1, X - 2, ...) - - -**Important** FULL_TRANSITIVE is the default compatibility mode in FDP, it is set at cluster level and all new schemas will inherit it - -This mode is preserved only if using the following operations - -- Adding optional fields (with default values) -- Delete optional fields (with default values) - -![Full compatibility](../../assets/sr_full_compat.png) - -#### Upgrading process of clients based on compatibility - -Depending on the compatibility mode, the process of upgrading producers/consumers will be different based on the compatibility mode enabled. - -- NONE - - As there are no compatibility checks, no order will grant a smooth transition - - In most of the cases this lead to having to create a new topic for this evolution -- BACKWARD / BACKWARD_TRANSITIVE - - Consumers **MUST** be upgraded first before producing new data - - No forward compatibility, meaning that there's no guarantee that the consumers with older schemas are going to be able to read data produced with a new version -- FORWARD / FORWARD_TRANSITIVE - - Producers **MUST** be upgraded first and then after ensuring that no older data is present, upgrade the consumers - - No backward compatibility, meaning that there's no guarantee that the consumers with newer schemas are going to be able to read data produced with an older version -- FULL / FULL TRANSITIVE - - No restrictions on the order, anything will work - - #### How to deal with breaking changes - -If for any reason you need to use a less strict compatibility mode in a topic, or you can't avoid breaking changes in a given situation, the compatibility mode **SHOULD NOT** be modified on the same topic. - -Instead, a new topic **SHOULD** be used to avoid unexpected behaviors or broken integrations. This allows a smooth transitioning from clients to the definitive topic, and once all clients are migrated the original one can be decommissioned. - -Alternatively, instead of modifying existing fields it **MAY** be considered as an suboptimal approach to add the changes in new fields and have both coexisting. Take into account that this pollutes your topic and it can cause some confusion. \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/g_key_value_format.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/g_key_value_format.md deleted file mode 100644 index ea3a280..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/g_key_value_format.md +++ /dev/null @@ -1,11 +0,0 @@ -# adidas Asynchronous API guidelines - -## Asynchronous API guidelines - - ### Key/Value message format - - Kafka messages **MAY** include a key, which needs to be properly designed to have a good balance of data across partitions. - -The message key and the payload (often called value) can be serialized independently and can have different formats. For example, the value of the message can be sent in AVRO format, while the message key can be a primitive type (string).  - -Message keys **SHOULD** be kept as simple as possible and use a primitive type when possible. \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/h_message_headers.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/h_message_headers.md deleted file mode 100644 index a2e024f..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/h_message_headers.md +++ /dev/null @@ -1,9 +0,0 @@ -# adidas Asynchronous API guidelines - -## Asynchronous API guidelines - -### Message headers - -In addition to the key and value, a Kafka message **MAY** include ***headers***, which allow to extend the information sent with some metadata as needed (for example, source of the data, routing or tracing information or any relevant information that could be useful without having to parse the message). - -Headers are just an ordered collection of key/value pairs, being the key a String and the value a serialized Object, the same as the message value itself. \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/i_naming_conventions.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/i_naming_conventions.md deleted file mode 100644 index 7f52d40..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/i_naming_conventions.md +++ /dev/null @@ -1,11 +0,0 @@ -# adidas Asynchronous API guidelines - -## Asynchronous API guidelines - -### Naming conventions - -As general naming conventions, asynchronous APIs **MUST** adhere to the following conventions - -- Use of english -- Avoid acronyms or explain them when used -- Use camelCase unless stated otherwise \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/j_protocols.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/j_protocols.md deleted file mode 100644 index 5b90ab4..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/j_protocols.md +++ /dev/null @@ -1,16 +0,0 @@ -# adidas Asynchronous API guidelines - -## Asynchronous API guidelines - -### Protocols - -Protocols define how clients and servers communicate in an asynchronous architecture. - -The accepted protocols for asynchronous APIs are: - -- Kafka -- HTTPs -- WebSockets -- MQTT - -This version of the guidelines focuses on Kafka protocol, but it could be extended in the future. In any case, this document will be updated to reflect the state of the art. \ No newline at end of file diff --git a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/k_security.md b/asynchronous-api-guidelines/02_asynchronous_api_guidelines/k_security.md deleted file mode 100644 index 5f8c20a..0000000 --- a/asynchronous-api-guidelines/02_asynchronous_api_guidelines/k_security.md +++ /dev/null @@ -1,7 +0,0 @@ -# adidas Asynchronous API guidelines - -## Asynchronous API guidelines - -### Security - -The [security guidelines](https://github.com/adidas/api-guidelines/blob/feature/asyncapi-guidelines/general-guidelines/security.md) for regular APIs **MUST** be followed strictly when applicable. \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/a_introduction.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/a_introduction.md deleted file mode 100644 index 293509d..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/a_introduction.md +++ /dev/null @@ -1,60 +0,0 @@ -# adidas Asynchronous API guidelines - -## Introduction to AsyncAPI spec definitions for Kafka protocol - -This section is specific to the definition of API specs with [AsyncAPI](https://www.asyncapi.com/) for Kafka protocol. - -Also, take into account that across the section there will be multiple references to this [AsyncAPI reference spec](https://design.api.3stripes.io/apis/adidas/asyncapi-adoption-initiative/1.0.0) which is publicly available for reference.  - -### Basic concepts about AsyncAPI - -#### Why AsyncAPI? - -Event-driven architectures are becoming increasingly popular for building scalable, responsive, and efficient applications. AsyncAPI plays a crucial role in this landscape by offering a standardized way to describe asynchronous APIs, similar to how OpenAPI does for REST APIs. AsyncAPI seeks to make the development, maintenance, and testing of asynchronous APIs easier by providing a machine-readable specification. - -It supports various messaging protocols, including MQTT, WebSocket, Kafka, AMQP, and more, making it versatile for different use cases. In adidas, we will use it mainly to document Kafka resources created in FDP but nothing prevents you from using it for a different purpose. - -The benefits of using AsyncAPI are, amongst others: - -- Standardization - - AsyncAPI defines a STANDARD format (YAML or JSON) for describing asynchronous APIs. - - By defining the structure of messages, channels, and events, you can ensure that all components adhere to the same conventions. - - Using a single standard ensures consistency in the design and documentation of all your asynchronous APIs. - - This simplifies integration, maintenance, and troubleshooting across different parts of your system. -- Improved Developer Experience - - AsyncAPI documents the messages being exchanged, their structure, and the events triggered by them. - - It provides developers with a clear picture of how to interact with the API, what data to expect, and how to interpret responses without digging into the implementation details.  -- Code scaffolding - - Using tools like asyncapi-generator allow to easily generate the skeleton of applications that can work with the resources described in the spec. - - This can be done in different programming languages (Python, Java, Node.js. ...), reducing significantly the development time and the coding errors. -- Design-first approach: It encourages designing the API first before writing code, leading to better planned and more reliable APIs. - -In addition to those benefits, Platform & Engineering is working hard to create a data catalogue built upon AsyncAPI that allows to have a good level of discoverability, allowing teams to be able to find exactly the data they need with regards to any data object in the company. - -Questions like: - -- Who is responsible for a specific data object -- Where is that data hosted -- Which kind of information is available - -Will be easy to answer once this catalogue is in place. Also, it is important to have a good discoverability and search & filtering capabilities. - -#### Kafka to AsyncAPI concept mapping - -|Kafka Concept|AsyncAPI Concept| -|-------------|----------------| -|broker|server| -|topic|channel| -|consumer|subscriber| -|producer|publisher| - -#### First level items in AsyncAPI structure - -|Element|Meaning| -|-------|-------| -|asyncapi|Specifies the AsyncAPI specification version| -|info|Provides metadata about the API such as the version, title and description| -|servers|Describes servers where the API is available| -|channels|Defines the channels through which messages are received/published| -|components|Reusable elements to be references across the spec| - diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/b_asyncapi_version.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/b_asyncapi_version.md deleted file mode 100644 index 295c23c..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/b_asyncapi_version.md +++ /dev/null @@ -1,14 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### AsyncAPI version - -Any version of AsyncAPI **MAY** be used for spec definitions. - -However, to be aligned with adidas tooling, spec versions **SHOULD** be *v2.6.0*, because to the date of this document creation (April 2024) this is the highest supported version on Swaggerhub, the current API portal to render, discover and publish specs. - -```yaml -asyncapi: 2.6.0 -... -``` \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/c_internal_public_specs.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/c_internal_public_specs.md deleted file mode 100644 index 4531323..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/c_internal_public_specs.md +++ /dev/null @@ -1,14 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Internal vs public specs - -AsyncAPI specs **MAY** be created both for public APIs or for internal APIs.  - -- Public APIs are those who are created to be consumed by others -- Internal APIs are only for development teams for a particular project - -There are no differences with regards to the spec definition, but internal APIs **SHOULD** have restricted access limited only to the internal development team for a particular project or product. - -This access control is handled through Role-Based Access Control (RBAC) implemented in Swaggerhub. \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/d_spec_granularity.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/d_spec_granularity.md deleted file mode 100644 index 8bf7253..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/d_spec_granularity.md +++ /dev/null @@ -1,11 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Spec granularity - -In Fast Data Platform (FDP) all resources are grouped by namespace. - -For that reason specs **SHOULD** be created with a relation 1:1 with namespaces. In other words, every namespace will have an AsyncAPI spec including all the assets belonging to that namespace. - -Different granularities **MAY** be chosen depending on the needs.  \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/e_meaningful_descriptions.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/e_meaningful_descriptions.md deleted file mode 100644 index 6570e85..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/e_meaningful_descriptions.md +++ /dev/null @@ -1,7 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Meaningful descriptions - -All fields included in the specs **MUST** include a proper description.  \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/f_self_contained_specs.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/f_self_contained_specs.md deleted file mode 100644 index dd18a12..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/f_self_contained_specs.md +++ /dev/null @@ -1,7 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Self-contained specs - -All AsyncAPI specs **SHOULD** include as much information as needed in order to make the spec self-contained and clearly documented \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/g_contact_information.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/g_contact_information.md deleted file mode 100644 index 072ad86..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/g_contact_information.md +++ /dev/null @@ -1,24 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Contact information - -AsyncAPI specs **MUST** include at least one main contact under the info.contact section. - -The spec only allows to include one contact there, but it **MAY** also include additional contacts using extension fields. In case this is done, it **MUST** use the extension field *x-additional-responsibles*. - -For example: - -```yaml -... -info: - ... - contact: - name: "Main point of contact" - email: "team_dl@adidas.com" - x-additional-responsibles: - - person2@adidas.com - - person3@adidas.com - - person4@adidas.com -``` \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/h_asyncapi_id.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/h_asyncapi_id.md deleted file mode 100644 index 644fd33..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/h_asyncapi_id.md +++ /dev/null @@ -1,15 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### AsyncAPI ID - -According to [AsyncAPI documentation](https://v2.asyncapi.com/docs/reference/specification/v2.6.0#A2SIdString), every AsyncAPI spec **SHOULD** use a unique identifier for the application being defined, following RFC-3986. - -More concretely, ASyncAPI specs created in adidas should use the following pattern - -```yaml -... -id: urn:fdp:adidas:com:namespace:asyncapi_reference_spec -... -``` \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/i_servers.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/i_servers.md deleted file mode 100644 index 6d20fb3..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/i_servers.md +++ /dev/null @@ -1,26 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Servers - -All AsyncAPI specs **MUST** include a servers section including references to the right Kafka clusters, defined and maintained by FDP team and made available through domains in Swaggerhub. - -Those definitions are handled in Swaggerhub as reusable domains publicly available: - -https://design.api.3stripes.io/domains/adidas/asyncapi_adoption_commons/1.0.0 - -that can be referred from any spec, picking the right kafka servers as required (see example below). - -```yaml -... -servers: - pivotalDev: - $ref: https://design.api.3stripes.io/v1/domains/adidas/asyncapi_adoption_commons/1.0.0#/components/servers/pivotalDev - pivotalSit: - $ref: https://design.api.3stripes.io/v1/domains/adidas/asyncapi_adoption_commons/1.0.0#/components/servers/pivotalSit - pivotalPro: - $ref: https://design.api.3stripes.io/v1/domains/adidas/asyncapi_adoption_commons/1.0.0#/components/servers/pivotalPro -... -``` -**Important note** Don't forget to include '*/v1/*' in the URL of the domain \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/j_channels.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/j_channels.md deleted file mode 100644 index ae628b3..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/j_channels.md +++ /dev/null @@ -1,92 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Channels - -All AsyncAPI specs **MUST** include definitions for the channels (kafka topics) including: - -- Description of the topic -- Servers in which the topic is available - - This is a reference to one of the server identifiers included in the servers section -- publish/subscribe operations - - Operation ID - - Summary or short description for the operation - - Description for the operation - - Security schemes - - Tags - - External Docs - - Message details - -In addition to those supported fields, it **MAY** be possible to use extension attributes (using the x- prefix) to specify specific configuration parameters and metadata. In so, the recommended attributes to use are : - -- x-metadata - - To include additional configuration specific to your team or project -- x-configurations - - To include Kafka configuration parameters and producers/consumers - -As the parameters can be different per environment, it is very convenient to add an additional level for the environment - -As part of the publish/subscribe operations, the spec **SHOULD** specify the different kafka clients currently consuming from the different topics for each cluster/environment. For this, the extended attributes x-producers and x-consumers will be used. - -```yaml -... -channels: - namespace.source.event.topic-name: - description: A description of the purpose of the topic and the contained information - servers: ["pivotalDev", "pivotalSit", "pivotalPro"] - x-metadata: - myField1: myValue1 - myField2: myValue2 - x-configurations: - pivotal.dev: - kafka: - partitions: 12 - replicas: 1 - topicConfiguration: - min.insync.replicas: "1" - retention.ms: "2592000000" - pivotal.sit: - kafka: - partitions: 12 - replicas: 2 - topicConfiguration: - min.insync.replicas: "1" - retention.ms: "2592000000" -    publish: - operationId: "producer" - summary: "Description for the operation" - description: "An extensive explanation about the operation" - security: - - producerAcl: [] - tags: - - name: tagA - - name: tagB - x-producers: - pivotal.dev: - - producer1 - - producer2 - pivotal.sit: - - producer1 - - producer2 - pivotal.pro: - - producer3 - - producer4 - externalDocs: - description: documentation - url: http://confluence.adidas.fdp/catalogue/myTopic - ... - subscribe: - operationId: "consumer" - ... - x-consumers: - pivotal.dev: - - consumer1 - - consumer2 - pivotal.sit: - - consumer1 - - consumer2 - pivotal.pro: - - consumer3 -... -``` \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/k_schemas.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/k_schemas.md deleted file mode 100644 index e0af361..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/k_schemas.md +++ /dev/null @@ -1,35 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Schemas - -Kafka messages **SHOULD** use schemas (AVRO, Json, Protobuf) registered in the Schema Registry to ensure compatibility between producers/consumers. - -If so, always refer to the schema definitions directly in the schema registry instead of duplicating the schema definitions inline. This is to avoid double maintenance.  - -An example directly taken from reference spec is shown below - -```yaml -... -channels: - namespace.source.event.topic-name: - ... - publish: - ... - message: - $ref: '#/components/messages/topic1Payload' -components: - ... - schemas: - ... - topic1SchemaValue: - schemaFormat: 'application/vnd.apache.avro;version=1.9.0' - payload: - $ref: https://sit-fdp-pivotal-schema-registry.api.3stripes.io/subjects/pea_fd_fdp.sample.test-value/versions/latest/schema - messages: - topic1Payload: - $ref: '#/components/schemas/topic1SchemaValue' -``` - -**Important note** The used schema is a very simple one, it is only used to illustrate how to refer to it. \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/l_security_schemes.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/l_security_schemes.md deleted file mode 100644 index 3c87c8c..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/l_security_schemes.md +++ /dev/null @@ -1,25 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### Security Schemes - -Specs **MAY** use security schemas to reflect the fact that the kafka servers use mTLS. It is something quite static at the moment so the recommendation is reuse the ones specified in the reference spec. - -```yaml -channels: - namespace.source.event.topic-name: - ... - publish: - ... - security: - - producerAcl: [] - ... -components: - securitySchemes: - ... - consumerAcl: - type: X509 - producerAcl: - type: X509 -``` \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/m_external_docs.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/m_external_docs.md deleted file mode 100644 index 64a76ed..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/m_external_docs.md +++ /dev/null @@ -1,14 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI guidelines for Kafka - -### External docs - -The external docs **SHOULD** be used to refer to LeanIX factsheet associated to the spec. - -```yaml -... -externalDocs: - description: LeanIX - url: https://adidas.leanix.net/adidasProduction/factsheet/Application/467ff391-876c-49ad-93bf-facafffc0178 -``` \ No newline at end of file diff --git a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/n_tooling.md b/asynchronous-api-guidelines/03_asyncapi_kafka_specs/n_tooling.md deleted file mode 100644 index 0c3d701..0000000 --- a/asynchronous-api-guidelines/03_asyncapi_kafka_specs/n_tooling.md +++ /dev/null @@ -1,44 +0,0 @@ -# adidas Asynchronous API guidelines - -## AsyncAPI tools - -### API Design platform - -The current platform available in adidas to design, host, and render AsyncAPI specs is [Swaggerhub](https://design.api.3stripes.io/). - -Every AsyncAPI spec **MUST** be hosted in Swaggerhub under the *adidas* organization. - -In the future, Fast Data Platform team will provide mechanisms to auto generate your specs as part of the self-service initiative that is ongoing. - -But until then, the specs will be created manually in the platform following the API-first approach if possible. - -**Important note** Swaggerhub has limited capabilities with regards to discoverability, search and filtering of APIs. Other alternatives are being evaluated. Any upcoming decision impacting this will be reflected in this document in the future. - -### Editors - -Aside from Swaggerhub editing capabilities, other alternative editor options are available: - -- AsyncAPI Studio: A web-based editor designed specifically for creating and validating AsyncAPI documents. -- Visual Studio Code: VS Code can be extended with plugins like "AsyncAPI for VS Code" to provide AsyncAPI-specific features,  for editing AsyncAPI files. - -### Command Line Interface (CLI) tool - -Unfortunately, Swaggerhub is not offering a Command Line Interface (CLI) tool which allows including this capability as part of CICD workflows.  - -For this, there is an official AsyncAPI CLI tool which can be checked here: https://www.asyncapi.com/tools/cli. This includes a validator against the AsyncAPI spec, templated generators, version conversion, spec optimizer, bundler, etc. - -For example, to validate a yaml spec file: - -``` -asyncapi validate --file your-asyncapi-file.yaml -``` - -### Generators - -These tools are capable of generate a variety of outputs from any valid AsyncAPI spec, including: - -- API documentation in various formats like HTML, Markdown, or OpenAPI -- Code samples in various programming languages like Python, Java, and Node.js based on your API definition.  -- Functionally complete applications - -There is an official generator tool which can be checked here: https://www.asyncapi.com/docs/tools/generator. \ No newline at end of file diff --git a/asynchronous-api-guidelines/asyncapi.md b/asynchronous-api-guidelines/asyncapi.md new file mode 100644 index 0000000..fbb29eb --- /dev/null +++ b/asynchronous-api-guidelines/asyncapi.md @@ -0,0 +1,6 @@ +# Introduction + +## adidas Asynchronous APIs Guidelines + + + diff --git a/asynchronous-api-guidelines/index.md b/asynchronous-api-guidelines/index.md deleted file mode 100644 index 4eec06a..0000000 --- a/asynchronous-api-guidelines/index.md +++ /dev/null @@ -1,34 +0,0 @@ -## Asynchronous API Guidelines - -* [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) - * [AsyncAPI version](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Internal vs Public specs](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Spec granularity](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Meaningful descriptions](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Self-contained specs](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Contact Information](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [AsyncAPI ID](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Servers](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Channels](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Schemas](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Security Schemes](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [External Docs](asynchronous-api-guidelines/03_asyncapi_kafka_specs) - * [Tooling](asynchronous-api-guidelines/03_asyncapi_kafka_specs)