Dapr SDK for go

Dapr SDK for Go

Client library to help you build Dapr application in Go. This client supports all public Dapr APIs while focusing on idiomatic Go experience and developer productivity.

Test Release Go Report Card GitHub go.mod Go version codecov

Usage

Assuming you already have installed Go

Dapr Go client includes two packages: client (for invoking public Dapr APIs), and service (to create services that will be invoked by Dapr, this is sometimes referred to as "callback").

Creating client

Import Dapr Go client package:

import "github.com/dapr/go-sdk/client"

Quick start

package main

import (
    dapr "github.com/dapr/go-sdk/client"
)

func main() {
    client, err := dapr.NewClient()
    if err != nil {
        panic(err)
    }
    defer client.Close()
    //TODO: use the client here, see below for examples 
}

Assuming you have Dapr CLI installed, you can then launch your app locally like this:

dapr run --app-id example-service \
         --app-protocol grpc \
         --app-port 50001 \
         go run main.go

See the example folder for more working Dapr client examples.

Usage

The Go client supports all the building blocks exposed by Dapr API. Let's review these one by one:

State

For simple use-cases, Dapr client provides easy to use Save, Get, and Delete methods:

ctx := context.Background()
data := []byte("hello")
store := "my-store" // defined in the component YAML 

// save state with the key key1, default options: strong, last-write
if err := client.SaveState(ctx, store, "key1", data); err != nil {
    panic(err)
}

// get state for key key1
item, err := client.GetState(ctx, store, "key1")
if err != nil {
    panic(err)
}
fmt.Printf("data [key:%s etag:%s]: %s", item.Key, item.Etag, string(item.Value))

// delete state for key key1
if err := client.DeleteState(ctx, store, "key1"); err != nil {
    panic(err)
}

For more granular control, the Dapr Go client exposes SetStateItem type, which can be used to gain more control over the state operations and allow for multiple items to be saved at once:

item1 := &dapr.SetStateItem{
    Key:  "key1",
    Etag: &ETag{
        Value: "1",
    },
    Metadata: map[string]string{
        "created-on": time.Now().UTC().String(),
    },
    Value: []byte("hello"),
    Options: &dapr.StateOptions{
        Concurrency: dapr.StateConcurrencyLastWrite,
        Consistency: dapr.StateConsistencyStrong,
    },
}

item2 := &dapr.SetStateItem{
    Key:  "key2",
    Metadata: map[string]string{
        "created-on": time.Now().UTC().String(),
    },
    Value: []byte("hello again"),
}

item3 := &dapr.SetStateItem{
    Key:  "key3",
    Etag: &dapr.ETag{
	Value: "1",
    },
    Value: []byte("hello again"),
}

if err := client.SaveBulkState(ctx, store, item1, item2, item3); err != nil {
    panic(err)
}

Similarly, GetBulkState method provides a way to retrieve multiple state items in a single operation:

keys := []string{"key1", "key2", "key3"}
items, err := client.GetBulkState(ctx, store, keys, nil,100)

And the ExecuteStateTransaction method to execute multiple upsert or delete operations transactionally.

ops := make([]*dapr.StateOperation, 0)

op1 := &dapr.StateOperation{
    Type: dapr.StateOperationTypeUpsert,
    Item: &dapr.SetStateItem{
        Key:   "key1",
        Value: []byte(data),
    },
}
op2 := &dapr.StateOperation{
    Type: dapr.StateOperationTypeDelete,
    Item: &dapr.SetStateItem{
        Key:   "key2",
    },
}
ops = append(ops, op1, op2)
meta := map[string]string{}
err := testClient.ExecuteStateTransaction(ctx, store, meta, ops)
PubSub

To publish data onto a topic, the Dapr client provides a simple method:

data := []byte(`{ "id": "a123", "value": "abcdefg", "valid": true }`)
if err := client.PublishEvent(ctx, "component-name", "topic-name", data); err != nil {
    panic(err)
}
Service Invocation

To invoke a specific method on another service running with Dapr sidecar, the Dapr client provides two options. To invoke a service without any data:

resp, err := client.InvokeMethod(ctx, "app-id", "method-name", "post")

And to invoke a service with data:

content := &dapr.DataContent{
    ContentType: "application/json",
    Data:        []byte(`{ "id": "a123", "value": "demo", "valid": true }`),
}

resp, err = client.InvokeMethodWithContent(ctx, "app-id", "method-name", "post", content)
Bindings

Similarly to Service, Dapr client provides two methods to invoke an operation on a Dapr-defined binding. Dapr supports input, output, and bidirectional bindings.

For simple, output only biding:

in := &dapr.InvokeBindingRequest{ Name: "binding-name", Operation: "operation-name" }
err = client.InvokeOutputBinding(ctx, in)

To invoke method with content and metadata:

in := &dapr.InvokeBindingRequest{
    Name:      "binding-name",
    Operation: "operation-name",
    Data: []byte("hello"),
    Metadata: map[string]string{"k1": "v1", "k2": "v2"},
}

out, err := client.InvokeBinding(ctx, in)
Secrets

The Dapr client also provides access to the runtime secrets that can be backed by any number of secrete stores (e.g. Kubernetes Secrets, HashiCorp Vault, or Azure KeyVault):

opt := map[string]string{
    "version": "2",
}

secret, err := client.GetSecret(ctx, "store-name", "secret-name", opt)
Authentication

By default, Dapr relies on the network boundary to limit access to its API. If however the target Dapr API is configured with token-based authentication, users can configure the Go Dapr client with that token in two ways:

Environment Variable

If the DAPR_API_TOKEN environment variable is defined, Dapr will automatically use it to augment its Dapr API invocations to ensure authentication.

Explicit Method

In addition, users can also set the API token explicitly on any Dapr client instance. This approach is helpful in cases when the user code needs to create multiple clients for different Dapr API endpoints.

func main() {
    client, err := dapr.NewClient()
    if err != nil {
        panic(err)
    }
    defer client.Close()
    client.WithAuthToken("your-Dapr-API-token-here")
}

Service (callback)

In addition to the client capabilities that allow you to call into the Dapr API, the Go SDK also provides service package to help you bootstrap Dapr callback services in either gRPC or HTTP. Instructions on how to use it are located here

Contributing to Dapr Go client

See the Contribution Guide to get started with building and developing.

Code of Conduct

Please refer to our Dapr Community Code of Conduct

Owner
Dapr
Distributed Application Runtime. An event-driven, portable runtime for building microservices on cloud and edge.
Dapr
Comments
  • Feat: Add Go-sdk Actor Support

    Feat: Add Go-sdk Actor Support

    I will finish this pr after the following procedures:

    1. Actor invoke with raw data success ✅
    2. Timer, Reminders, start and stop actor 's API support ✅
    3. client and server sides user friendly apis,serialization support ✅
    4. actor state support ✅ fix basic invoke support of #21
  • Rationalize PublishEvent* APIs

    Rationalize PublishEvent* APIs

    Allow passing options such as Content-Type and Metadata in a flexible and future-proof way. The method PublishEventfromCustomContent is now deprecated and shows a warning in the console when used. This PR maintains backwards compatibility.

    See #174 for context and discussion

    Fixes #174 Fixes #164

  • Change configuration API response to dictionary

    Change configuration API response to dictionary

    When https://github.com/dapr/dapr/pull/4695 merged, I will test the PR, then it should be reviewed by someone.

    the PR can be merged after that https://github.com/dapr/dapr/pull/4695 is merged.

    Related issues: #291

  • Expose GRPCClient.protoClient

    Expose GRPCClient.protoClient

    Is your feature request related to a problem? Please describe.

    In the GRPCClient struct, protoClient is the property that contains the lower-level gRPC client: https://github.com/dapr/go-sdk/blob/main/client/client.go#L165

    This is currently a private property, not exposed publicly. There are situations where applications may benefit from being able to interact with this object directly, having access to the lower-level gRPC APIs.

    Describe the solution you'd like

    Create a public getter method that returns the protoClient object so external objects can use it.

    Describe alternatives you've considered

    There are 2 alternatives for making low-level calls, but they're both sub-par:

    1. Using the Dapr HTTP APIs which don't require access to the gRPC object, but these are potentially slower and require fiddling with the correct request/response structs manually
    2. Creating a new gRPC connection, but it's less efficient than reusing the existing one.
  • introduces a flexible client configuration pattern

    introduces a flexible client configuration pattern

    For highly configurable clients, it's common to use a functional
    option pattern so the client API can change overtime without
    introducing backwards breaking patterns. The new functional options
    continue to expand variables and assume defaults as before. This
    eliminates the need for multiple constructors that are all creating
    the same dapr client in slightly different ways.
    
    The New() function purposely returns a concrete struct instead of an
    interface. This removes an unneeded abstraction and comes from the
    principal, "accept interfaces, return structs".
    
  • Custom go SDK (aka bespoke client proposal)

    Custom go SDK (aka bespoke client proposal)

    Custom go client that addresses issue #7 and hides much of the gRPC complexity and simplifies the interfaces with which the user interact. It also updates the calling service example to use the custom client

  • Implement HTTP service stop with a 5 sec timeout

    Implement HTTP service stop with a 5 sec timeout

    This addresses https://github.com/dapr/go-sdk/issues/208. It implements the Stop method on the HTTP service which is currently a no-op with a TODO comment.

    It sets a 5 second timeout for the shutdown process. Open to suggestions to avoid the time.Sleep in the tests or for a more appropriate shutdown timeout. Thanks for taking a look!

  • Add documentation and example to deal with gRPC 4mb limit

    Add documentation and example to deal with gRPC 4mb limit

    The approach is documented to deal with 4MB gRPC limit on client side with DAPR client.

    https://github.com/dapr/go-sdk/issues/189

    1. Example examples/service/custom-grpc-client/main.go have been added working demo.
    2. The README is updated at this location examples/service/README.md
    3. Entry in Makefile to run the example.
  • support metadata in state bulk get state

    support metadata in state bulk get state

    update GetBulkState method:

    1. add metedata parameter
    2. change return struct to BulkStateItem

    The details of this PR is discussed in dapr issue :

    https://github.com/dapr/dapr/issues/2368

    https://github.com/dapr/dapr/issues/2498

  • Rationalize PublishEvent* APIs

    Rationalize PublishEvent* APIs

    Currently, the Go SDK has 2 methods to publish events:

    The latter doesn't really do much more than the former, besides calling json.Marshal internally and setting the ContentType to application/json.

    With #173, I've proposed adding 2 more variants for those methods: PublishEventWithMetadata and PublishEventfromCustomContentWithMetadata (F is lowercased here for consistency). These address #164 and also allow doing things like setting the TTL.

    If #173 is merged (which I hope it is!) we will have 4 methods.

    Yet, there will still be things that can't be done: setting options that are already available in the protobuf definition, but can't be set using the higher-level PublishEvent* APIs. One example includes setting the ContentType of the document (it's set to text/plain for the "regular" methods and application/json for the "fromCustomContent" methods). In the future, we could expect that there will be other things that can't be set using the higher level APIs.

    I am proposing that the PublishEvent* APIs be rationalized:

    1. Ideally we would have less than 4 methods
    2. It should be possible to have access to a lower-level function that allows passing the protobuf object directly or a similar object (such as SaveBulkState for saving state)

    For example, it could be:

    • Deprecate PublishEventfromCustomContentWithMetadata and remove it in version 2.0
    • Change PublishEvent's last parameter to be interface{}:
      • If the argument is a []byte or string, it will maintain the current behavior
      • If it's a protobuf object or something similar to what SaveBulkState uses, then use that object which allows setting all options.
      • If it's something else, it will be JSON-ified like PublishEventfromCustomContentWithMetadata does today (and set content type to application/json)

    This will remain backwards-compatible today (PublishEventfromCustomContentWithMetadata can print a log message that it's deprecated but can continue to work until v2.0).

    I am happy to propose a PR if you accept this suggestion, or discuss it further.

  • Parameterize request method verb on service invocation

    Parameterize request method verb on service invocation

    dapr install in namespace myns, appid=myapp, and http handle router /test forward port on local:

    kubectl port-forward svc/myapp 50001:50001 3500:3500 8080:8080 -n myns
    

    invoke in go sdk:

     res, err := client.InvokeService(ctx, "myapp.myns", "test")
    

    this result is : error invoking service: rpc error: code = NotFound desc = Not Found

    browser open or call it use curl: http://localhost:3500/v1.0/invoke/myapp.myns/method/test it has correct result

    ps: Is there any other way to call the service locally

  • Ability to set http status code on response from a service method invocation

    Ability to set http status code on response from a service method invocation

    Is your feature request related to a problem? Please describe. At present, a service method invocation returns a (*common.Content, error) tuple. This allows the developer to specify the content type and the payload, but not the http response code.

    Describe the solution you'd like Add a statusCode field to the *common.Content struct, so that the sidecar can return that specific status code to the caller.

    Describe alternatives you've considered The only solution I have found reasonable is to write a a REST proxy that invokes the service method and translates the error code returned to an HTTP status code. Feasible, but unnecessary boilerplate.

    Additional context n/a

  • Gorilla Mux is no longer maintained

    Gorilla Mux is no longer maintained

    Is your feature request related to a problem? Please describe. I want to use the http service package in the SDK to subscribe to a pub-sub topic, but I don't want to use the NewService() function as I need to provide my own HTTP server/router. Previously I used NewServiceWithMux() however that only supports Gorilla.

    As of end of 2022 Gorilla Mux is no longer maintained, so I have moved to using Chi

    The package github.com/dapr/go-sdk/service/http is tightly bound to this now no longer supported library

    Describe the solution you'd like Support other popular Go HTTP libraries like Chi, Gin or Echo or find a more general purpose solution

    Describe alternatives you've considered Not using the Dapr SDK at all for subscripting to topics as it's needlessly complex, and providing very little benefit

    Additional context See post about Gorilla here https://github.com/gorilla#gorilla-toolkit

  • compile error occurs in package actor/state

    compile error occurs in package actor/state

    Describe the bug

    actor/state/state_async_provider.go cannot be compiled due to undeclared errors in log.Errorf.

    https://github.com/dapr/go-sdk/blob/718044ad12e5740807332874be9cc7f7a70985eb/actor/state/state_async_provider.go#L58-L65

    To Reproduce

    Run test in actor/state (or just open the source code in VSCode)

    $ go test
    # github.com/dapr/go-sdk/actor/state [github.com/dapr/go-sdk/actor/state.test]
    ./state_async_provider.go:59:7: undefined: log.Errorf
    ./state_async_provider.go:63:7: undefined: log.Errorf
    FAIL    github.com/dapr/go-sdk/actor/state [build failed]
    

    Expected behavior

    No compile errors occurs

  • Support for adding DeadLetterTopic setting for programatic subscriptions

    Support for adding DeadLetterTopic setting for programatic subscriptions

    Is your feature request related to a problem? Please describe.

    I am subscribing to the topic using a programmatic subscription as below:

    sub := &common.Subscription{
    	PubsubName: env.GetString("PUBSUB_NAME"),
    	Topic:      env.GetString("TOPIC_NAME"),
    	Metadata:   map[string]string{"consumerID": "{namespace}"},
    }
    

    I want to specify DeadLetterTopic for this subscription.

    Describe the solution you'd like

    Is it possible to add DeadLetterTopic to common.Subscription structure?

    Describe alternatives you've considered

    I thought of using a declarative subscription as an alternative but I am using grpc hence not sure how routing will work.

    Additional context

  • Add state TTL/expiry to Add/Set in actor state manager

    Add state TTL/expiry to Add/Set in actor state manager

    Is your feature request related to a problem? Please describe. We have a couple of use cases where actor state needs to expire reasonably quickly. In the general state store, setting a ttl is possible but this is not exposed in the Actor state management API (go-sdk).

    Describe the solution you'd like Allow state metadata to be passed in to Actor state management.

    Describe alternatives you've considered

    • Use a timer (this is what I will try next).
    • Fall back to using general state management which has metadata access, constructing per-actor keys.
    • Set actor lifetime to quite short and clear state on deactivation callback (is this even possible?)
Dapr is a portable, event-driven, runtime for building distributed applications across cloud and edge.
Dapr is a portable, event-driven, runtime for building distributed applications across cloud and edge.

Dapr is a portable, serverless, event-driven runtime that makes it easy for developers to build resilient, stateless and stateful microservices that run on the cloud and edge and embraces the diversity of languages and developer frameworks.

Jan 5, 2023
Collection of personal Dapr demos (bindings, state, pub/sub, service-to-service invocation)

Dapr demos Collection of personal Dapr demos. Note, some of these demos require latest version of Dapr, Ingress gateway, Observability components, or

Dec 10, 2022
A template project to demonstrate how to run WebAssembly functions as sidecar microservices in dapr
A template project to demonstrate how to run WebAssembly functions as sidecar microservices in dapr

Live Demo 1. Introduction DAPR is a portable, event-driven runtime that makes it easy for any developer to build resilient, stateless and stateful app

Jan 3, 2023
A customized middleware of DAPR.

A customized middleware of DAPR.

Dec 24, 2021
"From Zero to Hero with Go and Dapr" presented at GopherCon 2021

From Zero to Hero with Go and Dapr Slides This is a Go application demonstrating the key features of Dapr with a few different approaches. My goal is

Dec 30, 2022
A go sdk for baidu netdisk open platform 百度网盘开放平台 Go SDK

Pan Go Sdk 该代码库为百度网盘开放平台Go语言的SDK

Nov 22, 2022
Nextengine-sdk-go: the NextEngine SDK for the Go programming language

NextEngine SDK for Go nextengine-sdk-go is the NextEngine SDK for the Go programming language. Getting Started Install go get github.com/takaaki-s/nex

Dec 7, 2021
Commercetools-go-sdk is fork of original commercetools-go-sdk

commercetools-go-sdk The Commercetools Go SDK is automatically generated based on the official API specifications of Commercetools. It should therefor

Dec 13, 2021
Sdk-go - Go version of the Synapse SDK

synapsesdk-go Synapse Protocol's Go SDK. Currently in super duper alpha, do not

Jan 7, 2022
Redash-go-sdk - An SDK for the programmatic management of Redash, in Go
Redash-go-sdk - An SDK for the programmatic management of Redash, in Go

Redash Go SDK An SDK for the programmatic management of Redash. The main compone

Dec 13, 2022
AWS SDK for the Go programming language.

AWS SDK for Go aws-sdk-go is the official AWS SDK for the Go programming language. Checkout our release notes for information about the latest bug fix

Jan 1, 2023
The Couchbase Go SDK

Couchbase Go Client This is the official Couchbase Go SDK. If you are looking for our previous unofficial prototype Go client library, please see: htt

Dec 21, 2022
Scalable game server framework with clustering support and client libraries for iOS, Android, Unity and others through the C SDK.

pitaya Pitaya is an simple, fast and lightweight game server framework with clustering support and client libraries for iOS, Android, Unity and others

Jan 2, 2023
AWS SDK for the Go programming language.

AWS SDK for Go aws-sdk-go is the official AWS SDK for the Go programming language. Checkout our release notes for information about the latest bug fix

Dec 31, 2022
A Facebook Graph API SDK For Go.

A Facebook Graph API SDK In Golang This is a Go package that fully supports the Facebook Graph API with file upload, batch request and marketing API.

Dec 12, 2022
A Golang SDK for Medium's OAuth2 API

Medium SDK for Go This repository contains the open source SDK for integrating Medium's OAuth2 API into your Go app. Install go get github.com/Medium/

Nov 28, 2022
MinIO Client SDK for Go

MinIO Go Client SDK for Amazon S3 Compatible Cloud Storage The MinIO Go Client SDK provides simple APIs to access any Amazon S3 compatible object stor

Dec 29, 2022
Simple no frills AWS S3 Golang Library using REST with V4 Signing (without AWS Go SDK)

simples3 : Simple no frills AWS S3 Library using REST with V4 Signing Overview SimpleS3 is a golang library for uploading and deleting objects on S3 b

Nov 4, 2022
Twilight is an unofficial Golang SDK for Twilio APIs
Twilight is an unofficial Golang SDK for Twilio APIs

Twilight is an unofficial Golang SDK for Twilio APIs. Twilight was born as a result of my inability to spell Twilio correctly. I searched for a Twillio Golang client library and couldn’t find any, I decided to build one. Halfway through building this, I realized I had spelled Twilio as Twillio when searching for a client library on Github.

Jul 2, 2021
Wechat Pay SDK(V3) Write by Go.

WechatPay GO(v3) Introduction Wechat Pay SDK(V3) Write by Go. API V3 of Office document is here. Features Signature/Verify messages Encrypt/Decrypt ce

May 23, 2022