Go

Dapr offers packages to help with the development of Go pluggable components.

Prerequisites

Note

Development of Dapr pluggable components on Windows requires WSL. Not all languages and SDKs expose Unix Domain Sockets on “native” Windows.

Application creation

Creating a pluggable component starts with an empty Go application.

  1. mkdir example
  2. cd component
  3. go mod init example

Import Dapr packages

Import the Dapr pluggable components SDK package.

  1. go get github.com/dapr-sandbox/components-go-sdk@v0.1.0

Create main package

In main.go, import the Dapr plugggable components package and run the application.

  1. package main
  2. import (
  3. dapr "github.com/dapr-sandbox/components-go-sdk"
  4. )
  5. func main() {
  6. dapr.MustRun()
  7. }

This creates an application with no components. You will need to implement and register one or more components.

Implement and register components

Note

Only a single component of each type can be registered with an individual service. However, multiple components of the same type can be spread across multiple services.

Test components locally

Create the Dapr components socket directory

Dapr communicates with pluggable components via Unix Domain Sockets files in a common directory. By default, both Dapr and pluggable components use the /tmp/dapr-components-sockets directory. You should create this directory if it does not already exist.

  1. mkdir /tmp/dapr-components-sockets

Start the pluggable component

Pluggable components can be tested by starting the application on the command line.

To start the component, in the application directory:

  1. go run main.go

Configure Dapr to use the pluggable component

To configure Dapr to use the component, create a component YAML file in the resources directory. For example, for a state store component:

  1. apiVersion: dapr.io/v1alpha1
  2. kind: Component
  3. metadata:
  4. name: <component name>
  5. spec:
  6. type: state.<socket name>
  7. version: v1
  8. metadata:
  9. - name: key1
  10. value: value1
  11. - name: key2
  12. value: value2

Any metadata properties will be passed to the component via its Store.Init(metadata state.Metadata) method when the component is instantiated.

Start Dapr

To start Dapr (and, optionally, the service making use of the service):

  1. dapr run --app-id <app id> --resources-path <resources path> ...

At this point, the Dapr sidecar will have started and connected via Unix Domain Socket to the component. You can then interact with the component either:

  • Through the service using the component (if started), or
  • By using the Dapr HTTP or gRPC API directly

Create container

Pluggable components are deployed as containers that run as sidecars to the application (like Dapr itself). A typical Dockerfile for creating a Docker image for a Go application might look like:

  1. FROM golang:1.20-alpine AS builder
  2. WORKDIR /usr/src/app
  3. # Download dependencies
  4. COPY go.mod go.sum ./
  5. RUN go mod download && go mod verify
  6. # Build the application
  7. COPY . .
  8. RUN go build -v -o /usr/src/bin/app .
  9. FROM alpine:latest
  10. # Setup non-root user and permissions
  11. RUN addgroup -S app && adduser -S app -G app
  12. RUN mkdir /tmp/dapr-components-sockets && chown app /tmp/dapr-components-sockets
  13. # Copy application to runtime image
  14. COPY --from=builder --chown=app /usr/src/bin/app /app
  15. USER app
  16. CMD ["/app"]

Build the image:

  1. docker build -f Dockerfile -t <image name>:<tag> .

Note

Paths for COPY operations in the Dockerfile are relative to the Docker context passed when building the image, while the Docker context itself will vary depending on the needs of the application being built. In the example above, the assumption is that the Docker context is the component application directory.

Next steps