diff --git a/daprdocs/content/en/developing-applications/building-blocks/_index.md b/daprdocs/content/en/developing-applications/building-blocks/_index.md index d0df0b4aa..6546d234e 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/_index.md +++ b/daprdocs/content/en/developing-applications/building-blocks/_index.md @@ -1,11 +1,11 @@ --- type: docs -title: "Building blocks" -linkTitle: "Building blocks" +title: "API building blocks" +linkTitle: "API building blocks" weight: 10 description: "Dapr capabilities that solve common development challenges for distributed applications" --- -Get a high-level [overview of Dapr building blocks]({{< ref building-blocks-concept >}}) in the **Concepts** section. +Get a high-level [overview of Dapr API building blocks]({{< ref building-blocks-concept >}}) in the **Concepts** section. Diagram showing the different Dapr API building blocks \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/debugging/_index.md b/daprdocs/content/en/developing-applications/debugging/_index.md index d6d77e77d..bb9d76df1 100644 --- a/daprdocs/content/en/developing-applications/debugging/_index.md +++ b/daprdocs/content/en/developing-applications/debugging/_index.md @@ -2,6 +2,6 @@ type: docs title: "Debugging Dapr applications and the Dapr control plane" linkTitle: "Debugging" -weight: 60 +weight: 50 description: "Guides on how to debug Dapr applications and the Dapr control plane" --- \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/develop-components/_index.md b/daprdocs/content/en/developing-applications/develop-components/_index.md new file mode 100644 index 000000000..cb9f7e8a8 --- /dev/null +++ b/daprdocs/content/en/developing-applications/develop-components/_index.md @@ -0,0 +1,7 @@ +--- +type: docs +title: "Components" +linkTitle: "Components" +weight: 30 +description: "Learn more about developing Dapr's pluggable and middleware components" +--- diff --git a/daprdocs/content/en/developing-applications/develop-components/develop-middleware.md b/daprdocs/content/en/developing-applications/develop-components/develop-middleware.md new file mode 100644 index 000000000..31874b473 --- /dev/null +++ b/daprdocs/content/en/developing-applications/develop-components/develop-middleware.md @@ -0,0 +1,47 @@ +--- +type: docs +title: "How to: Author middleware components" +linkTitle: "Middleware components" +weight: 200 +description: "Learn how to develop middleware components" +aliases: + - /developing-applications/middleware/middleware-overview/ + - /concepts/middleware-concept/ +--- + +Dapr allows custom processing pipelines to be defined by chaining a series of middleware components. There are two places that you can use a middleware pipeline; + +1) Building block APIs - HTTP middleware components are executed when invoking any Dapr HTTP APIs. +2) Service-to-Service invocation - HTTP middleware components are applied to service-to-service invocation calls. + +## Writing a custom middleware + +Dapr uses [FastHTTP](https://github.com/valyala/fasthttp) to implement its HTTP server. Hence, your HTTP middleware needs to be written as a FastHTTP handler. Your middleware needs to implement a middleware interface, which defines a **GetHandler** method that returns **fasthttp.RequestHandler** and **error**: + +```go +type Middleware interface { + GetHandler(metadata Metadata) (func(h fasthttp.RequestHandler) fasthttp.RequestHandler, error) +} +``` + +Your handler implementation can include any inbound logic, outbound logic, or both: + +```go + +func (m *customMiddleware) GetHandler(metadata Metadata) (func(fasthttp.RequestHandler) fasthttp.RequestHandler, error) { + var err error + return func(h fasthttp.RequestHandler) fasthttp.RequestHandler { + return func(ctx *fasthttp.RequestCtx) { + // inbound logic + h(ctx) // call the downstream handler + // outbound logic + } + }, err +} +``` + +## Related links + +- [Component schema]({{< ref component-schema.md >}}) +- [Configuration overview]({{< ref configuration-overview.md >}}) +- [API middleware sample](https://github.com/dapr/samples/tree/master/middleware-oauth-google) diff --git a/daprdocs/content/en/operations/components/pluggable-components/_index.md b/daprdocs/content/en/developing-applications/develop-components/pluggable-components/_index.md similarity index 67% rename from daprdocs/content/en/operations/components/pluggable-components/_index.md rename to daprdocs/content/en/developing-applications/develop-components/pluggable-components/_index.md index d6a82273e..82ed69cbb 100644 --- a/daprdocs/content/en/operations/components/pluggable-components/_index.md +++ b/daprdocs/content/en/developing-applications/develop-components/pluggable-components/_index.md @@ -1,9 +1,9 @@ --- type: docs -title: "Pluggable Components" -linkTitle: "Pluggable Components" +title: "Pluggable components" +linkTitle: "Pluggable components" description: "Guidance on how to work with pluggable components" -weight: 4000 +weight: 100 aliases: - "/operations/components/pluggable-components/pluggable-components-overview/" ---- +--- \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/develop-components/pluggable-components/develop-pluggable.md b/daprdocs/content/en/developing-applications/develop-components/pluggable-components/develop-pluggable.md new file mode 100644 index 000000000..e3f92b1e5 --- /dev/null +++ b/daprdocs/content/en/developing-applications/develop-components/pluggable-components/develop-pluggable.md @@ -0,0 +1,112 @@ +--- +type: docs +title: "How to: Implement pluggable components" +linkTitle: "Pluggable components" +weight: 1100 +description: "Learn how to author and implement pluggable components" +--- + +In this guide, you'll learn why and how to implement a [pluggable component]({{< ref pluggable-components-overview >}}). To learn how to configure and register a pluggable component, refer to [How to: Register a pluggable component]({{< ref pluggable-components-registration.md >}}) + +## Implement a pluggable component + +In order to implement a pluggable component, you need to implement a gRPC service in the component. Implementing the gRPC service requires three steps: + +### Find the proto definition file + +Proto definitions are provided for each supported service interface (state store, pub/sub, bindings). + +Currently, the following component APIs are supported: + +- State stores +- Pub/sub +- Bindings + +| Component | Type | gRPC definition | Built-in Reference Implementation | Docs | +| :---------: | :--------: | :--------------: | :----------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| State Store | `state` | [state.proto] | [Redis](https://github.com/dapr/components-contrib/tree/master/state/redis) | [concept]({{< ref "state-management-overview" >}}), [howto]({{< ref "howto-get-save-state" >}}), [api spec]({{< ref "state_api" >}}) | +| Pub/sub | `pubsub` | [pubsub.proto] | [Redis](https://github.com/dapr/components-contrib/tree/master/pubsub/redis) | [concept]({{< ref "pubsub-overview" >}}), [howto]({{< ref "howto-publish-subscribe" >}}), [api spec]({{< ref "pubsub_api" >}}) | +| Bindings | `bindings` | [bindings.proto] | [Kafka](https://github.com/dapr/components-contrib/tree/master/bindings/kafka) | [concept]({{< ref "bindings-overview" >}}), [input howto]({{< ref "howto-triggers" >}}), [output howto]({{< ref "howto-bindings" >}}), [api spec]({{< ref "bindings_api" >}}) | + +Below is a snippet of the gRPC service definition for pluggable component state stores ([state.proto]): + +```protobuf +// StateStore service provides a gRPC interface for state store components. +service StateStore { + // Initializes the state store component with the given metadata. + rpc Init(InitRequest) returns (InitResponse) {} + // Returns a list of implemented state store features. + rpc Features(FeaturesRequest) returns (FeaturesResponse) {} + // Ping the state store. Used for liveness purposes. + rpc Ping(PingRequest) returns (PingResponse) {} + + // Deletes the specified key from the state store. + rpc Delete(DeleteRequest) returns (DeleteResponse) {} + // Get data from the given key. + rpc Get(GetRequest) returns (GetResponse) {} + // Sets the value of the specified key. + rpc Set(SetRequest) returns (SetResponse) {} + + + // Deletes many keys at once. + rpc BulkDelete(BulkDeleteRequest) returns (BulkDeleteResponse) {} + // Retrieves many keys at once. + rpc BulkGet(BulkGetRequest) returns (BulkGetResponse) {} + // Set the value of many keys at once. + rpc BulkSet(BulkSetRequest) returns (BulkSetResponse) {} +} +``` + +The interface for the `StateStore` service exposes a total of 9 methods: + +- 2 methods for initialization and components capability advertisement (Init and Features) +- 1 method for health-ness or liveness check (Ping) +- 3 methods for CRUD (Get, Set, Delete) +- 3 methods for bulk CRUD operations (BulkGet, BulkSet, BulkDelete) + +### Create service scaffolding + +Use [protocol buffers and gRPC tools](https://grpc.io) to create the necessary scaffolding for the service. Learn more about these tools via [the gRPC concepts documentation](https://grpc.io/docs/what-is-grpc/core-concepts/). + +These tools generate code targeting [any gRPC-supported language](https://grpc.io/docs/what-is-grpc/introduction/#protocol-buffer-versions). This code serves as the base for your server and it provides: +- Functionality to handle client calls +- Infrastructure to: + - Decode incoming requests + - Execute service methods + - Encode service responses + +The generated code is incomplete. It is missing: + +- A concrete implementation for the methods your target service defines (the core of your pluggable component). +- Code on how to handle Unix Socket Domain integration, which is Dapr specific. +- Code handling integration with your downstream services. + +Learn more about filling these gaps in the next step. + +### Define the service + +Provide a concrete implementation of the desired service. Each component has a gRPC service definition for its core functionality which is the same as the core component interface. For example: + +- **State stores** + + A pluggable state store **must** provide an implementation of the `StateStore` service interface. + + In addition to this core functionality, some components might also expose functionality under other **optional** services. For example, you can add extra functionality by defining the implementation for a `QueriableStateStore` service and a `TransactionalStateStore` service. + +- **Pub/sub** + + Pluggable pub/sub components only have a single core service interface defined ([pubsub.proto]). They have no optional service interfaces. + +- **Bindings** + + Pluggable input and output bindings have a single core service definition on [bindings.proto]. They have no optional service interfaces. + +After generating the above state store example's service scaffolding code using gRPC and protocol buffers tools, you can define concrete implementations for the 9 methods defined under `service StateStore`, along with code to initialize and communicate with your dependencies. + +This concrete implementation and auxiliary code are the **core** of your pluggable component. They define how your component behaves when handling gRPC requests from Dapr. + +## Next steps + +- Get started with developing .NET pluggable component using this [sample code](https://github.com/dapr/samples/tree/master/pluggable-components-dotnet-template) +- [Review the pluggable components overview]({{< ref pluggable-components-overview.md >}}) +- [Learn how to register your pluggable component]({{< ref pluggable-components-registration >}}) \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/develop-components/pluggable-components/pluggable-components-overview.md b/daprdocs/content/en/developing-applications/develop-components/pluggable-components/pluggable-components-overview.md new file mode 100644 index 000000000..96b1260cc --- /dev/null +++ b/daprdocs/content/en/developing-applications/develop-components/pluggable-components/pluggable-components-overview.md @@ -0,0 +1,69 @@ +--- +type: docs +title: "Pluggable components overview" +linkTitle: "Overview" +weight: 1000 +description: "Overview of pluggable component anatomy and supported component types" +--- + +Pluggable components are components that are not included as part the runtime, as opposed to the built-in components included with `dapr init`. You can configure Dapr to use pluggable components that leverage the building block APIs, but are registered differently from the [built-in Dapr components](https://github.com/dapr/components-contrib). + + + +## Pluggable components vs. built-in components + +Dapr provides two approaches for registering and creating components: + +- The built-in components included in the runtime and found in the [components-contrib repository ](https://github.com/dapr/components-contrib). +- Pluggable components which are deployed and registered independently. + +While both registration options leverage Dapr's building block APIs, each has a different implementation processes. + +| Component details | [Built-in Component](https://github.com/dapr/components-contrib/blob/master/docs/developing-component.md) | Pluggable Components | +| ---------------------------- | :--------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Language** | Can only be written in Go | [Can be written in any gRPC-supported language](https://grpc.io/docs/what-is-grpc/introduction/#protocol-buffer-versions) | +| **Where it runs** | As part of the Dapr runtime executable | As a distinct process or container in a pod. Runs separate from Dapr itself. | +| **Registers with Dapr** | Included into the Dapr codebase | Registers with Dapr via Unix Domain Sockets (using gRPC ) | +| **Distribution** | Distributed with Dapr release. New features added to component are aligned with Dapr releases | Distributed independently from Dapr itself. New features can be added when needed and follows its own release cycle. | +| **How component is activated** | Dapr starts runs the component (automatic) | User starts component (manual) | + +## Why create a pluggable component? + +Pluggable components prove useful in scenarios where: + +- You require a private component. +- You want to keep your component separate from the Dapr release process. +- You are not as familiar with Go, or implementing your component in Go is not ideal. + +## Features + +### Implement a pluggable component + +In order to implement a pluggable component, you need to implement a gRPC service in the component. Implementing the gRPC service requires three steps: + +1. Find the proto definition file +1. Create service scaffolding +1. Define the service + +Learn more about [how to develop and implement a pluggable component]({{< ref develop-pluggable.md >}}) + +### Leverage multiple building blocks for a component + +In addition to implementing multiple gRPC services from the same component (for example `StateStore`, `QueriableStateStore`, `TransactionalStateStore` etc.), a pluggable component can also expose implementations for other component interfaces. This means that a single pluggable component can simultaneously function as a state store, pub/sub, and input or output binding. In other words, you can implement multiple component interfaces into a pluggable component and expose them as gRPC services. + +While exposing multiple component interfaces on the same pluggable component lowers the operational burden of deploying multiple components, it makes implementing and debugging your component harder. If in doubt, stick to a "separation of concerns" by merging multiple components interfaces into the same pluggable component only when necessary. + +## Operationalize a pluggable component + +Built-in components and pluggable components share one thing in common: both need a [component specification]({{< ref "components-concept.md#component-specification" >}}). Built-in components do not require any extra steps to be used: Dapr is ready to use them automatically. + +In contrast, pluggable components require additional steps before they can communicate with Dapr. You need to first run the component and facilitate Dapr-component communication to kick off the registration process. + +## Next steps + +- [Implement a pluggable component]({{< ref develop-pluggable.md >}}) +- [Pluggable component registration]({{< ref "pluggable-components-registration" >}}) + +[state.proto]: https://github.com/dapr/dapr/blob/master/dapr/proto/components/v1/state.proto +[pubsub.proto]: https://github.com/dapr/dapr/blob/master/dapr/proto/components/v1/pubsub.proto +[bindings.proto]: https://github.com/dapr/dapr/blob/master/dapr/proto/components/v1/bindings.proto diff --git a/daprdocs/content/en/developing-applications/integrations/_index.md b/daprdocs/content/en/developing-applications/integrations/_index.md index 337db1c12..a884aeb5c 100644 --- a/daprdocs/content/en/developing-applications/integrations/_index.md +++ b/daprdocs/content/en/developing-applications/integrations/_index.md @@ -2,6 +2,6 @@ type: docs title: "Integrations" linkTitle: "Integrations" -weight: 10 +weight: 60 description: "Dapr integrations with other technologies" --- \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/local-development/_index.md b/daprdocs/content/en/developing-applications/local-development/_index.md new file mode 100644 index 000000000..b06587df5 --- /dev/null +++ b/daprdocs/content/en/developing-applications/local-development/_index.md @@ -0,0 +1,7 @@ +--- +type: docs +title: "Local development" +linkTitle: "Local development" +weight: 40 +description: "Capabilities for developing Dapr applications locally" +--- \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/ides/_index.md b/daprdocs/content/en/developing-applications/local-development/ides/_index.md similarity index 90% rename from daprdocs/content/en/developing-applications/ides/_index.md rename to daprdocs/content/en/developing-applications/local-development/ides/_index.md index f74c56e54..7c9bc6dfa 100644 --- a/daprdocs/content/en/developing-applications/ides/_index.md +++ b/daprdocs/content/en/developing-applications/local-development/ides/_index.md @@ -2,6 +2,6 @@ type: docs title: "IDE support" linkTitle: "IDE support" -weight: 30 +weight: 200 description: "Support for common Integrated Development Environments (IDEs)" --- \ No newline at end of file diff --git a/daprdocs/content/en/developing-applications/ides/intellij.md b/daprdocs/content/en/developing-applications/local-development/ides/intellij.md similarity index 100% rename from daprdocs/content/en/developing-applications/ides/intellij.md rename to daprdocs/content/en/developing-applications/local-development/ides/intellij.md diff --git a/daprdocs/content/en/developing-applications/ides/vscode/_index.md b/daprdocs/content/en/developing-applications/local-development/ides/vscode/_index.md similarity index 100% rename from daprdocs/content/en/developing-applications/ides/vscode/_index.md rename to daprdocs/content/en/developing-applications/local-development/ides/vscode/_index.md diff --git a/daprdocs/content/en/developing-applications/ides/vscode/vscode-dapr-extension.md b/daprdocs/content/en/developing-applications/local-development/ides/vscode/vscode-dapr-extension.md similarity index 100% rename from daprdocs/content/en/developing-applications/ides/vscode/vscode-dapr-extension.md rename to daprdocs/content/en/developing-applications/local-development/ides/vscode/vscode-dapr-extension.md diff --git a/daprdocs/content/en/developing-applications/ides/vscode/vscode-how-to-debug-multiple-dapr-apps.md b/daprdocs/content/en/developing-applications/local-development/ides/vscode/vscode-how-to-debug-multiple-dapr-apps.md similarity index 100% rename from daprdocs/content/en/developing-applications/ides/vscode/vscode-how-to-debug-multiple-dapr-apps.md rename to daprdocs/content/en/developing-applications/local-development/ides/vscode/vscode-how-to-debug-multiple-dapr-apps.md diff --git a/daprdocs/content/en/developing-applications/ides/vscode/vscode-remote-dev-containers.md b/daprdocs/content/en/developing-applications/local-development/ides/vscode/vscode-remote-dev-containers.md similarity index 100% rename from daprdocs/content/en/developing-applications/ides/vscode/vscode-remote-dev-containers.md rename to daprdocs/content/en/developing-applications/local-development/ides/vscode/vscode-remote-dev-containers.md diff --git a/daprdocs/content/en/operations/components/component-scopes.md b/daprdocs/content/en/operations/components/component-scopes.md index 4b878caed..b24a4273a 100644 --- a/daprdocs/content/en/operations/components/component-scopes.md +++ b/daprdocs/content/en/operations/components/component-scopes.md @@ -2,7 +2,7 @@ type: docs title: "How-To: Scope components to one or more applications" linkTitle: "Scope access to components" -weight: 300 +weight: 400 description: "Limit component access to particular Dapr instances" --- diff --git a/daprdocs/content/en/operations/components/component-secrets.md b/daprdocs/content/en/operations/components/component-secrets.md index d5e0ef056..b7e1f0a51 100644 --- a/daprdocs/content/en/operations/components/component-secrets.md +++ b/daprdocs/content/en/operations/components/component-secrets.md @@ -2,7 +2,7 @@ type: docs title: "How-To: Reference secrets in components" linkTitle: "Reference secrets in components" -weight: 400 +weight: 500 description: "How to securly reference secrets from a component definition" --- diff --git a/daprdocs/content/en/operations/components/component-updates.md b/daprdocs/content/en/operations/components/component-updates.md index 287638d1f..583eee28e 100644 --- a/daprdocs/content/en/operations/components/component-updates.md +++ b/daprdocs/content/en/operations/components/component-updates.md @@ -2,7 +2,7 @@ type: docs title: "Updating components" linkTitle: "Updating components" -weight: 250 +weight: 300 description: "Updating deployed components used by applications" --- diff --git a/daprdocs/content/en/developing-applications/middleware.md b/daprdocs/content/en/operations/components/middleware.md similarity index 75% rename from daprdocs/content/en/developing-applications/middleware.md rename to daprdocs/content/en/operations/components/middleware.md index 705f46fea..270ca5f19 100644 --- a/daprdocs/content/en/developing-applications/middleware.md +++ b/daprdocs/content/en/operations/components/middleware.md @@ -1,12 +1,9 @@ --- type: docs -title: "Middleware" -linkTitle: "Middleware" -weight: 50 +title: "Configure middleware components" +linkTitle: "Configure middleware" +weight: 2000 description: "Customize processing pipelines by adding middleware components" -aliases: - - /developing-applications/middleware/middleware-overview/ - - /concepts/middleware-concept/ --- Dapr allows custom processing pipelines to be defined by chaining a series of middleware components. There are two places that you can use a middleware pipeline; @@ -14,7 +11,7 @@ Dapr allows custom processing pipelines to be defined by chaining a series of mi 1) Building block APIs - HTTP middleware components are executed when invoking any Dapr HTTP APIs. 2) Service-to-Service invocation - HTTP middleware components are applied to service-to-service invocation calls. -## Configuring API middleware pipelines +## Configure API middleware pipelines When launched, a Dapr sidecar constructs a middleware processing pipeline for incoming HTTP calls. By default, the pipeline consists of [tracing middleware]({{< ref tracing-overview.md >}}) and CORS middleware. Additional middleware, configured by a Dapr [configuration]({{< ref configuration-concept.md >}}), can be added to the pipeline in the order they are defined. The pipeline applies to all Dapr API endpoints, including state, pub/sub, service invocation, bindings, secrets, configuration, distributed lock, and others. @@ -45,7 +42,7 @@ As with other components, middleware components can be found in the [supported M {{< button page="supported-middleware" text="See all middleware components">}} -## Configuring app middleware pipelines +## Configure app middleware pipelines You can also use any middleware components when making service-to-service invocation calls. For example, for token validation in a zero-trust environment, a request transformation for a specific app endpoint, or to apply OAuth policies. @@ -68,35 +65,9 @@ spec: type: middleware.http.uppercase ``` - -## Writing a custom middleware - -Dapr uses [FastHTTP](https://github.com/valyala/fasthttp) to implement its HTTP server. Hence, your HTTP middleware needs to be written as a FastHTTP handler. Your middleware needs to implement a middleware interface, which defines a **GetHandler** method that returns **fasthttp.RequestHandler** and **error**: - -```go -type Middleware interface { - GetHandler(metadata Metadata) (func(h fasthttp.RequestHandler) fasthttp.RequestHandler, error) -} -``` - -Your handler implementation can include any inbound logic, outbound logic, or both: - -```go - -func (m *customMiddleware) GetHandler(metadata Metadata) (func(fasthttp.RequestHandler) fasthttp.RequestHandler, error) { - var err error - return func(h fasthttp.RequestHandler) fasthttp.RequestHandler { - return func(ctx *fasthttp.RequestCtx) { - // inbound logic - h(ctx) // call the downstream handler - // outbound logic - } - }, err -} -``` - ## Related links +- [Learn how to author middleware components]({{< ref develop-middleware.md >}}) - [Component schema]({{< ref component-schema.md >}}) - [Configuration overview]({{< ref configuration-overview.md >}}) - [API middleware sample](https://github.com/dapr/samples/tree/master/middleware-oauth-google) diff --git a/daprdocs/content/en/operations/components/pluggable-components/pluggable-components-registration.md b/daprdocs/content/en/operations/components/pluggable-components-registration.md similarity index 96% rename from daprdocs/content/en/operations/components/pluggable-components/pluggable-components-registration.md rename to daprdocs/content/en/operations/components/pluggable-components-registration.md index 068780d3b..d7e91e347 100644 --- a/daprdocs/content/en/operations/components/pluggable-components/pluggable-components-registration.md +++ b/daprdocs/content/en/operations/components/pluggable-components-registration.md @@ -1,8 +1,8 @@ --- type: docs title: "How-To: Register a pluggable component" -linkTitle: "How To: Register a pluggable component" -weight: 4500 +linkTitle: "Register a pluggable component" +weight: 1000 description: "Learn how to register a pluggable component" --- @@ -10,7 +10,7 @@ description: "Learn how to register a pluggable component" ## Component registration process -Pluggable, [gRPC-based](https://grpc.io/) components are typically run as containers or processes that need to communicate with the Dapr runtime via [Unix Domain Sockets][uds]. They are automatically discovered and registered in the runtime with the following steps: +[Pluggable, gRPC-based components]({{< ref pluggable-components-overview >}}) are typically run as containers or processes that need to communicate with the Dapr runtime via [Unix Domain Sockets][uds]. They are automatically discovered and registered in the runtime with the following steps: 1. The component listens to an [Unix Domain Socket][uds] placed on the shared volume. 2. The Dapr runtime lists all [Unix Domain Socket][uds] in the shared volume. diff --git a/daprdocs/content/en/operations/components/pluggable-components/pluggable-components-overview.md b/daprdocs/content/en/operations/components/pluggable-components/pluggable-components-overview.md deleted file mode 100644 index 247259d8a..000000000 --- a/daprdocs/content/en/operations/components/pluggable-components/pluggable-components-overview.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -type: docs -title: "Pluggable components overview" -linkTitle: "Overview" -weight: 4400 -description: "Overview of pluggable component anatomy and supported component types" ---- - -Pluggable components are components that are not included as part the runtime, as opposed to built-in ones that are included. You can configure Dapr to use pluggable components that leverage the building block APIs, but these are registered differently from the [built-in Dapr components](https://github.com/dapr/components-contrib). For example, you can configure a pluggable component for scenarios where you require a private component. - - - -## Pluggable components vs. built-in components - -Dapr provides two approaches for registering and creating components: - -- The built-in components included in the runtime and found in the [components-contrib repository ](https://github.com/dapr/components-contrib). -- Pluggable components which are deployed and registered independently. - -While both registration options leverage Dapr's building block APIs, each has a different implementation processes. - -| Component details | [Built-in Component](https://github.com/dapr/components-contrib/blob/master/docs/developing-component.md) | Pluggable Components | -| ---------------------------- | :--------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Language** | Can only be written in Go | [Can be written in any gRPC-supported language](https://grpc.io/docs/what-is-grpc/introduction/#protocol-buffer-versions) | -| **Where it runs** | As part of the Dapr runtime executable | As a distinct process or container in a pod. Runs separate from Dapr itself. | -| **Registers with Dapr** | Included into the Dapr codebase | Registers with Dapr via Unix Domain Sockets (using gRPC ) | -| **Distribution** | Distributed with Dapr release. New features added to component are aligned with Dapr releases | Distributed independently from Dapr itself. New features can be added when needed and follows its own release cycle. | -| **How component is activated** | Dapr starts runs the component (automatic) | User starts component (manual) | - -## When to create a pluggable component - -- This is a private component. -- You want to keep your component separate from the Dapr release process. -- You are not as familiar with Go, or implementing your component in Go is not ideal. - -## Implementing a pluggable component - -In order to implement a pluggable component you need to implement a gRPC service in the component. Implementing the gRPC service requires three steps: - -1. **Find the proto definition file.** Proto definitions are provided for each supported service interface (state store, pub/sub, bindings). - -Currently, the following component APIs are supported: - -- State stores -- Pub/sub -- Bindings - - -| Component | Type | gRPC definition | Built-in Reference Implementation | Docs | -| :---------: | :--------: | :--------------: | :----------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| State Store | `state` | [state.proto] | [Redis](https://github.com/dapr/components-contrib/tree/master/state/redis) | [concept]({{}}), [howto]({{}}), [api spec]({{}}) | -| Pub/sub | `pubsub` | [pubsub.proto] | [Redis](https://github.com/dapr/components-contrib/tree/master/pubsub/redis) | [concept]({{}}), [howto]({{}}), [api spec]({{}}) | -| Bindings | `bindings` | [bindings.proto] | [Kafka](https://github.com/dapr/components-contrib/tree/master/bindings/kafka) | [concept]({{}}), [input howto]({{}}), [output howto]({{}}), [api spec]({{}}) | - -Here's a snippet of the gRPC service definition for pluggable component state stores ([state.proto]). - -```protobuf -// StateStore service provides a gRPC interface for state store components. -service StateStore { - // Initializes the state store component with the given metadata. - rpc Init(InitRequest) returns (InitResponse) {} - // Returns a list of implemented state store features. - rpc Features(FeaturesRequest) returns (FeaturesResponse) {} - // Ping the state store. Used for liveness purposes. - rpc Ping(PingRequest) returns (PingResponse) {} - - // Deletes the specified key from the state store. - rpc Delete(DeleteRequest) returns (DeleteResponse) {} - // Get data from the given key. - rpc Get(GetRequest) returns (GetResponse) {} - // Sets the value of the specified key. - rpc Set(SetRequest) returns (SetResponse) {} - - - // Deletes many keys at once. - rpc BulkDelete(BulkDeleteRequest) returns (BulkDeleteResponse) {} - // Retrieves many keys at once. - rpc BulkGet(BulkGetRequest) returns (BulkGetResponse) {} - // Set the value of many keys at once. - rpc BulkSet(BulkSetRequest) returns (BulkSetResponse) {} -} -``` - -The interface for the `StateStore` service exposes 9 methods: - -- 2 methods for initialization and components capability advertisement (Init and Features) -- 1 method for health-ness or liveness check (Ping) -- 3 methods for CRUD (Get, Set, Delete) -- 3 methods for bulk CRUD operations (BulkGet, BulkSet, BulkDelete) - -2. **Create service scaffolding.** Use [protocol buffers and gRPC tools](https://grpc.io) to create the necessary scaffolding for the service. You may want to get acquainted with [the gRPC concepts documentation](https://grpc.io/docs/what-is-grpc/core-concepts/). - -The tools can generate code targeting [any gRPC-supported language](https://grpc.io/docs/what-is-grpc/introduction/#protocol-buffer-versions). This code serves as the base for your server and it provides functionality to handle client calls along with infrastructure to decode incoming requests, execute service methods, and encode service responses. - -The generated code is not complete. It is missing a concrete implementation for the methods your target service defines, i.e., the core of your pluggable component. This is further explored in the next topic. Additionally, you also have to provide code on how to handle Unix Socket Domain integration, which is Dapr specific, and code handling integration with your downstream services. - -3. **Define the service.** Provide a concrete implementation of the desired service. - -As a first step, [protocol buffers](https://developers.google.com/protocol-buffers/docs/overview) and [gRPC](https://grpc.io/docs/what-is-grpc/introduction/) tools are used to create the server code for this service. After that, the next step is to define concrete implementations for these 9 methods. - -Each component has a gRPC service definition for its core functionality which is the same as the core component interface. For example: - -- **State stores** -A pluggable state store **must** provide an implementation of the `StateStore` service interface. In addition to this core functionality, some components might also expose functionality under other **optional** services. For example, you can add extra functionality by defining the implementation for a `QueriableStateStore` service and a `TransactionalStateStore` service. - -- **Pub/sub** - Pluggable pub/sub components only have a single core service interface defined ([pubsub.proto]). They have no optional service interfaces. - -- **Bindings** - Pluggable input and output bindings have a single core service definition on [bindings.proto]. They have no optional service interfaces. - -Following the State Store example from step 1, after generating its service scaffolding code using gRPC and protocol buffers tools (step 2), -the next step is to define concrete implementations for the 9 methods defined under `service StateStore`, along with code to initialize and communicate with your dependencies. -This concrete implementation and auxiliary code are the core of your pluggable component: they define how your component behaves when handling gRPC requests from Dapr. - -### Leveraging multiple building blocks for a component - -In addition to implementing multiple gRPC services from the same component (for example `StateStore`, `QueriableStateStore`, `TransactionalStateStore` etc.), a pluggable component can also expose implementations for other component interfaces. This means that a single pluggable component can function as a state store, pub/sub, and input or output binding, all at the same time. In other words, you can implement multiple component interfaces into a pluggable component and exposes these as gRPC services. - -While exposing multiple component interfaces on the same pluggable component lowers the operational burden of deploying multiple components, it makes implementing and debugging your component harder. If in doubt, stick to a "separation of concerns" by merging multiple components interfaces into the same pluggable component only when necessary. - -## Operationalizing a pluggable component - -Built-in components and pluggable components share one thing in common: both need a [component specification]({{}}). Built-in components do not require any extra steps to be used: Dapr is ready to use them automatically. - -In contrast, pluggable components require additional steps before they can communicate with Dapr. You need to first run the component and facilitate Dapr-component communication to kick off the registration process. - -## Next steps - -- [Pluggable component registration]({{}}) - -[state.proto]: https://github.com/dapr/dapr/blob/master/dapr/proto/components/v1/state.proto -[pubsub.proto]: https://github.com/dapr/dapr/blob/master/dapr/proto/components/v1/pubsub.proto -[bindings.proto]: https://github.com/dapr/dapr/blob/master/dapr/proto/components/v1/bindings.proto diff --git a/daprdocs/content/en/operations/components/setup-bindings.md b/daprdocs/content/en/operations/components/setup-bindings.md index 7f1ba34eb..3af31760c 100644 --- a/daprdocs/content/en/operations/components/setup-bindings.md +++ b/daprdocs/content/en/operations/components/setup-bindings.md @@ -3,7 +3,7 @@ type: docs title: "Bindings components" linkTitle: "Bindings" description: "Guidance on setting up Dapr bindings components" -weight: 4000 +weight: 900 --- Dapr integrates with external resources to allow apps to both be triggered by external events and interact with the resources. Each binding component has a name and this name is used when interacting with the resource. diff --git a/daprdocs/content/en/operations/components/setup-pubsub/_index.md b/daprdocs/content/en/operations/components/setup-pubsub/_index.md index 1df2e94d8..aa3255aa5 100644 --- a/daprdocs/content/en/operations/components/setup-pubsub/_index.md +++ b/daprdocs/content/en/operations/components/setup-pubsub/_index.md @@ -3,7 +3,7 @@ type: docs title: "Pub/Sub brokers" linkTitle: "Pub/sub brokers" description: "Guidance on setting up different message brokers for Dapr Pub/Sub" -weight: 2000 +weight: 700 aliases: - "/operations/components/setup-pubsub/setup-pubsub-overview/" --- diff --git a/daprdocs/content/en/operations/components/setup-pubsub/pubsub-namespaces.md b/daprdocs/content/en/operations/components/setup-pubsub/pubsub-namespaces.md index d2ed4b4c4..81099ca5c 100644 --- a/daprdocs/content/en/operations/components/setup-pubsub/pubsub-namespaces.md +++ b/daprdocs/content/en/operations/components/setup-pubsub/pubsub-namespaces.md @@ -2,7 +2,7 @@ type: docs title: "HowTo: Configure Pub/Sub components with multiple namespaces" linkTitle: "Multiple namespaces" -weight: 20000 +weight: 10000 description: "Use Dapr Pub/Sub with multiple namespaces" --- diff --git a/daprdocs/content/en/operations/components/setup-secret-store.md b/daprdocs/content/en/operations/components/setup-secret-store.md index 307ba0e2d..bd4190c2a 100644 --- a/daprdocs/content/en/operations/components/setup-secret-store.md +++ b/daprdocs/content/en/operations/components/setup-secret-store.md @@ -3,7 +3,7 @@ type: docs title: "Secret store components" linkTitle: "Secret stores" description: "Guidance on setting up different secret store components" -weight: 3000 +weight: 800 aliases: - "/operations/components/setup-state-store/secret-stores-overview/" --- diff --git a/daprdocs/content/en/operations/components/setup-state-store.md b/daprdocs/content/en/operations/components/setup-state-store.md index db4e06b3b..6c1fc74f6 100644 --- a/daprdocs/content/en/operations/components/setup-state-store.md +++ b/daprdocs/content/en/operations/components/setup-state-store.md @@ -3,7 +3,7 @@ type: docs title: "State stores components" linkTitle: "State stores" description: "Guidance on setting up different state stores for Dapr state management" -weight: 1000 +weight: 600 aliases: - "/operations/components/setup-state-store/setup-state-store-overview/" ---