Skip to content

Commit

Permalink
Docs/customizer (#47)
Browse files Browse the repository at this point in the history
* feat: Add section for customizer

Resolves #39

* chore: Spelling of Springwolf/AsyncAPI/OpenAPI

* feat: Add AsyncApiCustomizer example

* Update customizing.md

---------

Co-authored-by: sam0r040 <[email protected]>
  • Loading branch information
timonback and sam0r040 authored Jul 28, 2023
1 parent 8724218 commit c257b36
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 25 deletions.
22 changes: 11 additions & 11 deletions docs/behind-the-scenes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,39 @@ sidebar_position: 70

# Behind the scenes

The following paragraphs describe how springwolf works internally.
The following paragraphs describe how Springwolf works internally.

## Big Picture
When the Spring Boot application is started, springwolf uses its scanners to find defined consumers and producers within the application.
When the Spring Boot application is started, Springwolf uses its scanners to find defined consumers and producers within the application.
Based on the results, the channels/topics are extracted including payload type and merged together into an [AsyncApi conform document](https://www.asyncapi.com/docs/reference/specification/v2.6.0).

The AsyncApi document is accessible an endpoint.
When the springwolf ui is opened, the browser fetches the document and renders it (see demo).
The AsyncAPI document is accessible an endpoint.
When the Springwolf ui is opened, the browser fetches the document and renders it (see demo).

When publishing is enabled, the user can publish a message through the ui to another endpoint.
From there, springwolf forwards the message to the protocol specific producer.
From there, Springwolf forwards the message to the protocol specific producer.

## Plugins
`springwolf-core` provides the base functionality to orchestrate the scanning and building of the AsyncApi document.
`springwolf-core` provides the base functionality to orchestrate the scanning and building of the AsyncAPI document.
The different protocol (AMQP, Kafka) are supported through plugins.
These plugins are found through the Spring dependency injection functionality.
When building own scanner plugins, your plugin will need to implement the `ChannelsScanner` interface.

## Scanners
`springwolf-core` runs all scanners and merges the found results together into one AsyncApi document.
`springwolf-core` runs all scanners and merges the found results together into one AsyncAPI document.
When the same channel/topic is found multiple times, it is merged as well.

The result is a [`ChannelItem`](https://www.asyncapi.com/docs/reference/specification/v2.6.0#channelItemObject).
The `ChannelItem` contains the `Message` for the subscribe and/or publish operation.

## Building an example payload
When the scanners scan and build the result, they also extract the payload type.
The payload is registered in the `SchemasService`, which allows to split the `Message` from the schema definition - within the AsyncApi doc a `$ref` references is used.
The payload is registered in the `SchemasService`, which allows to split the `Message` from the schema definition - within the AsyncAPI doc a `$ref` references is used.

Using `swagger-inflector` any class can be converted into a OpenApi schema.
This is used to instantiate an Example object with default values and serialized into an example json for the AsyncApi document.
Using `swagger-parser` any class can be converted into a OpenAPI schema.
The schema is then used to serialized it into an example json for the AsyncAPI document.

By using `swagger-inflector`, all the `@Schema` and other swagger annotations are supported as well as `@JsonProperty` through the use of the objectmapper.
By using `swagger-parser`, all the `@Schema` and other swagger annotations are supported as well as `@JsonProperty` through the use of the objectmapper.

### ModelConverters
ModelConverters provide a way to improve documentation for classes, which cannot be modified, for example because they are part of an external library.
Expand Down
4 changes: 2 additions & 2 deletions docs/configuration/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import CodeConfigurationAsyncApiDocket from '!!raw-loader!./snippets/_configurat

# Configuration

There are 2 ways to configure springwolf which cannot be combined:
There are 2 ways to configure Springwolf which cannot be combined:

1. `application.properties`, which is simple and moves all configuration to this file and annotations
2. (deprecated) `AsyncApiDocket`, which allows adding producers and consumers via code (instead of annotations)
Expand Down Expand Up @@ -61,7 +61,7 @@ The following table contains additional properties that can be specified in the

| Property Name | Default Value | Description |
|----------------------------------------------------------|--------------------|---------------------------------------------------------------------------------------------------------------------------|
| `springwolf.enabled` | `true` | Allows to enable/disable springwolf at one central place. |
| `springwolf.enabled` | `true` | Allows to enable/disable Springwolf at one central place. |
| `springwolf.paths.docs` | `/springwolf/docs` | The path of the AsyncAPI document in JSON format. *Note that at the moment the UI will work only with the default value.* |
| `springwolf.scanner.consumer-data.enabled` | `true` | Enable scanner to find consumers defined in `AsyncApiDocket`. |
| `springwolf.scanner.producer-data.enabled` | `true` | Enable scanner to find producers defined in `AsyncApiDocket`. |
Expand Down
41 changes: 41 additions & 0 deletions docs/configuration/customizing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
sidebar_position: 80
---

# Customizing
Adding and changing functionality of Springwolf is easy.
The [configuration](../configuration/configuration.md) page mentions the existing ones.

When you feel that Springwolf is missing a feature, you are able to add it yourself.
To learn more about how Springwolf works, look [behind the scenes](../behind-the-scenes.md).

:::note
Please let us know on GitHub or Discord, so that other people can benefit from it as well.
[Contributions are welcome, here are some basic tips](https://github.com/springwolf/springwolf-core/blob/master/CONTRIBUTING.md).
:::

Springwolf uses interfaces to allow to inject functionality at integration points.
Springwolf provides default implementation, but those can be replaced.
All default implementations are Spring managed beans, which can be overridden.

## `AsyncApiCustomizer` - Full AsyncAPI document

By implementing the `AsyncApiCustomizer`, the AsyncAPI document can be modified after Springwolf has done all the scanning and has built the document.
It is the final interception point before the document is available to the user.

For example, the title can be adjusted - although this should be done through the configuration:
```java
@Component
public class AsyncApiTitleCustomizer implements AsyncApiCustomizer {
@Override
public void customize(AsyncAPI asyncAPI) {
asyncAPI.getInfo().setTitle("Title set through customizer");
}
}
```

## `ChannelScanners` - Channel detection

All `ChannelScanner` beans are called to scan for channels.
This interface is helpful when a protocol currently unsupported by Springwolf is used.
Remember to register all payloads in the `SchemasService`.
4 changes: 2 additions & 2 deletions docs/configuration/documenting-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void sendMessage(ExamplePayloadDto msg) {

## Schema

Under the hood springwolf relies on swagger-core `ModelConverters` to define the message schema.
Under the hood Springwolf relies on swagger-core `ModelConverters` to define the message schema.

By default, the type and example values for the properties are guessed.
The default Jackson `ModelResolver` supports schema definitions via `@Schema` to overwrite the property definitions.
Expand All @@ -44,7 +44,7 @@ The default Jackson `ModelResolver` supports schema definitions via `@Schema` to

The `@Schema` annotation allows to set many properties like `description`, `example`, `requiredMode` to document payloads.

All properties are part of the produced AsyncApi file. However, not all of them are displayed in springwolf-ui. The ones listed above are included.
All properties are part of the produced AsyncApi file. However, not all of them are displayed in Springwolf-ui. The ones listed above are included.

### Usage

Expand Down
12 changes: 6 additions & 6 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ sidebar_position: 80

## General

### Is springwolf free? What is the license?
### Is Springwolf free? What is the license?

Yes, you can use springwolf for private and commercial purposes as long as you comply to the [Apache License 2.0](https://github.com/springwolf/springwolf-core/blob/master/LICENSE).
Yes, you can use Springwolf for private and commercial purposes as long as you comply to the [Apache License 2.0](https://github.com/springwolf/springwolf-core/blob/master/LICENSE).

## Troubleshooting

### The springwolf UI is not showing
### The Springwolf UI is not showing

When the `springwolf-ui` dependency is added, the ui should be visible at [http://localhost:8080/springwolf/asyncapi-ui.html](http://localhost:8080/springwolf/asyncapi-ui.html).

Expand Down Expand Up @@ -45,7 +45,7 @@ Spring Security allows to limit access to authorized users.

### Is Spring Boot 2.X supported?

You can use an older version of springwolf, which is build to support Spring Boot 2.X.
You can use an older version of Springwolf, which is build to support Spring Boot 2.X.
However, these versions do not get any updates.

Last versions to support Spring Boot 2.X:
Expand All @@ -66,7 +66,7 @@ Use the `AsyncApiService` to access the generated documentation.
#### With Gradle

You can use the [springdoc-openapi-gradle-plugin](https://github.com/springdoc/springdoc-openapi-gradle-plugin) and configure the plugin
for springwolf by pointing it to the springwolf docs endpoint:
for Springwolf by pointing it to the Springwolf docs endpoint:

```groovy
openApi {
Expand All @@ -87,7 +87,7 @@ properties can help you.

### My consumers are detected multiple times (with different payloads)

When springwolf finds multiple consumers/producers for the same channel/topic, these are merged together.
When Springwolf finds multiple consumers/producers for the same channel/topic, these are merged together.
This is expected, as there are use-cases where different payloads are sent via the same channel/topic.

Springwolf uses on scanners to find all consumer and producers in your application.
Expand Down
4 changes: 2 additions & 2 deletions docs/introduction/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sidebar_position: 10

# Introduction

## What is springwolf
## What is Springwolf
API Documentation is an important part of every project and product, but can be painful to maintain manually.
Spring Boot projects have great solutions for auto-generated documentation for REST APIs to overcome this pain (such as springfox, or springdoc-openapi).

Expand All @@ -14,7 +14,7 @@ Springwolf is compliant to [AsyncAPI](https://www.asyncapi.com), which brings th

### Demo

View the [live demo](https://demo.springwolf.dev) of springwolf in action.
View the [live demo](https://demo.springwolf.dev) of Springwolf in action.

Also, the demos of the
[amqp](https://amqp.demo.springwolf.dev),
Expand Down
4 changes: 2 additions & 2 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ springwolf.docket.servers.kafka.protocol=kafka
springwolf.docket.servers.kafka.url=${kafka.bootstrap.servers:localhost:29092}
```

*Make sure to change the value of `springwolf.docket.base-package` to the package containing your listeners, so that springwolf will automatically pick them up.*
*Make sure to change the value of `springwolf.docket.base-package` to the package containing your listeners, so that Springwolf will automatically pick them up.*

## 3. View the docs
Start the application and open the urls in your browser:
- Json: [`<host>:<port>/springwolf/docs`](http://localhost:8080/springwolf/docs)
- Yaml: [`<host>:<port>/springwolf/docs.yaml`](http://localhost:8080/springwolf/docs.yaml)
- UI: [`<host>:<port>/springwolf/asyncapi-ui.html`](http://localhost:8080/springwolf/asyncapi-ui.html)

If you configured a different context path in your application, make sure to prepend it to springwolf urls, i.e. `<host>:<port>/<context-path>/springwolf/asyncapi-ui.html`
If you configured a different context path in your application, make sure to prepend it to Springwolf urls, i.e. `<host>:<port>/<context-path>/springwolf/asyncapi-ui.html`

## 4. Next steps

Expand Down

0 comments on commit c257b36

Please sign in to comment.