Dapr has gRPC and REST APIs. For go
, there is an auto-generated gRPC SDK and the developers can also implement their own HTTP calls to the REST API. When invoking the dapr REST APIs there usually is lot's of redundant code building request, parsing responses, and dealing with traces. I create this client to simplify Dapr integrations and minimize code duplication.
Note, I submitted a PR with similar enhancements to the go-sdk already submitted #18
To use godapr
first get the library
go get github.com/mchmarny/godapr/v1
To use godapr
library in your code, first import it
import dapr "github.com/mchmarny/godapr/v1"
Then create a godapr
client with the dapr
server defaults
client := dapr.NewClient()
or if you need to specify non-default dapr port
client := dapr.NewClientWithURL("http://localhost:3500")
To save state using the the "reasonable" defaults:
state := "my data"
err := client.SaveState(ctx, "store-name", "id-123", state)
You can also persist objects
person := &Person{ Name: "Example John", Age: 35 }
err := client.SaveState(ctx, "store-name", "id-123", person)
For more control, you can also create the StateData
object
data := &StateData{
Key: "id-123",
Value: person,
Options: &StateOptions{
Consistency: "eventual",
Concurrency: "first-write",
},
}
err := client.SaveStateWithData(ctx, "store-name", data)
To get state data you can either use the client defaults ("strong" Consistency, "last-write" Concurrency)
data, err := client.GetState(ctx, "store-name", "record-key")
Or, for more control, define your own state options
opt := &StateOptions{
Consistency: "eventual",
Concurrency: "first-write",
}
data, err := client.GetStateWithOptions(ctx, "store-name", "record-key", opt)
data
contains the []byte
content retrieved from the state store
Similarly with deleting, you can either use the defaults
err := client.DeleteState(ctx, "store-name", "record-key")
Or define your own state data object
opt := &StateOptions{
Consistency: "eventual",
Concurrency: "first-write",
}
err := client.DeleteStateWithOptions(ctx, "store-name", opt)
To publish events to a topic you can pass instance of your own struct
err := client.Publish(ctx, "topic-name", person)
Or send the raw content in bytes
data := []byte("hi")
err := client.PublishWithData(ctx, "topic-name", data)
Similarly with binding, you can invoke binding without any data
out, err := client.InvokeBinding(ctx, "binding-name", "create")
Or, with an instance of your own struct
out, err := client.InvokeBindingWithIdentity(ctx, "binding-name", "create", person)
Or, for more control, with an instance of the BindingData
data := &BindingData{
Data: []byte("your content"),
Operation: "create",
Metadata: map[string]string{ "k1":"v1", "k2": "v2" },
}
out, err := client.InvokeBindingWithData(ctx, "binding-name", "create", data)
out
contains the []byte
content returned by the binding
Similarly with service to service invocation, you can invoke without any data
out, err := client.InvokeService(ctx, "service-name", "method-name")
Or, with an instance of your own struct
out, err := client.InvokeServiceWithIdentity(ctx, "service-name", "method-name", person)
Or, invoke it directly with your own content
data := []byte("your content")
out, err := client.InvokeServiceWithData(ctx, "binding-name", "create", data)
out
contains the []byte
content returned by the service
This is my personal project and it does not represent my employer. I take no responsibility for issues caused by this code. I do my best to ensure that everything works, but if something goes wrong, my apologies is all you will get.
This software is released under the Apache v2 License