{"id":27148094,"url":"https://github.com/rotationalio/go-ensign","last_synced_at":"2025-04-08T11:52:27.017Z","repository":{"id":130013016,"uuid":"607400279","full_name":"rotationalio/go-ensign","owner":"rotationalio","description":"Ensign driver, SDK, and helpers for Golang","archived":false,"fork":false,"pushed_at":"2023-10-23T01:08:40.000Z","size":290,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2023-10-23T02:25:16.382Z","etag":null,"topics":["driver","event-driven","eventing","microservices","sdk","sdk-go"],"latest_commit_sha":null,"homepage":"https://ensign.rotational.dev/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rotationalio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-02-27T22:35:08.000Z","updated_at":"2023-10-23T02:25:22.509Z","dependencies_parsed_at":null,"dependency_job_id":"cbd74046-6582-4da9-8a7c-27d8023dd280","html_url":"https://github.com/rotationalio/go-ensign","commit_stats":null,"previous_names":[],"tags_count":12,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rotationalio%2Fgo-ensign","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rotationalio%2Fgo-ensign/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rotationalio%2Fgo-ensign/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rotationalio%2Fgo-ensign/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rotationalio","download_url":"https://codeload.github.com/rotationalio/go-ensign/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247838402,"owners_count":21004576,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["driver","event-driven","eventing","microservices","sdk","sdk-go"],"created_at":"2025-04-08T11:52:26.383Z","updated_at":"2025-04-08T11:52:27.008Z","avatar_url":"https://github.com/rotationalio.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ensign Go SDK\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/rotationalio/go-ensign.svg)](https://pkg.go.dev/github.com/rotationalio/go-ensign)\n[![Go Report Card](https://goreportcard.com/badge/github.com/rotationalio/go-ensign)](https://goreportcard.com/report/github.com/rotationalio/go-ensign)\n[![CI](https://github.com/rotationalio/go-ensign/actions/workflows/test.yaml/badge.svg)](https://github.com/rotationalio/go-ensign/actions/workflows/test.yaml)\n\nWelcome to go-ensign!\n\nThis repository contains the Ensign driver, SDK, and helpers for Go. For the main ensign repo, go [here](https://github.com/rotationalio/ensign). We also have SDKs for [Javascript](https://github.com/rotationalio/ensignjs) and [Python](https://github.com/rotationalio/pyensign).\n\nThe getting started guide and general documentation can be found at [https://ensign.rotational.dev](https://ensign.rotational.dev). You may also want to reference the [GoDoc Package Documentation](https://pkg.go.dev/github.com/rotationalio/go-ensign) as well.\n\n## Creating an Ensign Client\n\nTo add the Go SDK as a dependency, either `go get` it or import it and run `go mod tidy`:\n\n```\n$ go get github.com/rotationalio/go-ensign\n```\n\nThe Go SDK provides a client that is able to connect to an Ensign system in order to manage topics, publish events, and subscribe to an event stream. At a minimum, you need API credentials, which can be obtained by creating an account at [https://rotational.app](https://rotational.app). Once you've created an account and downloaded your credentials, you can instantiate a new Ensign client and check to make sure you're connected:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/rotationalio/go-ensign\"\n)\n\nfunc main() {\n\tclient, err := ensign.New(ensign.WithCredentials(\"CLIENT ID\", \"CLIENT SECRET\"))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tstatus, err := client.Status(context.Background())\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", status)\n}\n```\n\nYou can also set the `$ENSIGN_CLIENT_ID` and `$ENSIGN_CLIENT_SECRET` environment\nvariables so that you can instantiate the Client without specifying credentials in code.\n\n```go\n// Assumes that $ENSIGN_CLIENT_ID and $ENSIGN_CLIENT_SECRET are set\nclient, err := ensign.New()\n```\n\nFinally, if you downloaded the `client.json` file from the app; you can load it by specifying the path to the JSON file:\n\n\n```go\nclient, err := ensign.New(ensign.WithLoadCredentials(\"path/to/client.json\"))\n```\n\n## Topic Management\n\nEvery topic that you work with is like a database table or collection of tables -- it is where your event data lives. Naturally, this is generally a starting place to interacting with Ensign. While you can create and manage topics from [Beacon](https://rotational.app) -- our Ensign UI -- you can also create and manage topics with the SDK.\n\nGenerally speaking, at the beginning of each Ensign program, you'll want to check if a topic exists and create it if it doesn't. This can be done with the following code:\n\n```go\nconst TopicName = \"my-awesome-topic\"\n\nvar client *ensign.Client\n\nfunc checkTopic() (err error) {\n\tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n\tdefer cancel()\n\n\tvar exists bool\n\tif exists, err = client.TopicExists(ctx, TopicName); err != nil {\n\t\treturn err\n\t}\n\n\tif !exists {\n\t\tvar topicID string\n\t\tif topicID, err = client.CreateTopic(ctx, TopicName); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlog.Printf(\"created topic %s with ID %s\\n\", TopicName, topicID)\n\t}\n\treturn nil\n}\n```\n\nYou can also list all the topics in your current project as follows:\n\n```go\nfunc printAllTopics() error {\n\tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n\tdefer cancel()\n\n\ttopics, err := client.ListTopics(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, topic := range topics {\n\t\tfmt.Printf(\"%s: %s\\n\", topic.Id, topic.Name)\n\t}\n\treturn nil\n}\n```\n\n### Topic Cache\n\nIf you're going to be working with a lot of topics, you can use the `topics.Cache` to simplify topic management. Create the cache as follows:\n\n```go\n\nimport (\n\t\"github.com/rotationalio/ensign\"\n\tensignTopics \"github.com/rotationalio/ensign/topics\"\n)\n\nvar (\n\tclient *ensign.Client\n\ttopics *ensignTopics.Cache\n)\n\nfunc connect() (err error) {\n\tif client, err = ensign.New(); err != nil {\n\t\treturn err\n\t}\n\n\ttopics = ensignTopics.NewCache(client)\n\treturn nil\n}\n```\n\nWith the topics cache in place you can simplify the \"check if topic exists and create if it doesn't\" code by using the `Ensure()` method:\n\n```go\nconst TopicName = \"my-awesome-topic\"\n\nfunc checkTopic() (err error) {\n\tif _, err = topics.Ensure(TopicName); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n```\n\nThe cache also prevents repeated calls to Ensign, so you can use the `Exists` and `Get` method instead of `client.TopicExists` and `client.TopicID`.\n\n## Events\n\nThe [`Event`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Event) data structure is how you can create data to send to Ensign and your downstream subscribers, and how you will receive data from Ensign. At it's core, an event is an application-defined datagram that you can use to create totally ordered data flows.\n\nThere are two pieces user-specified information that are part of the event, the `Metadata`: user-defined key/value pairs of strings that can be used for querying and indexing events, and the `Data`, generic data that you can use that define the event.\n\nTo parse and work with events, there are two pieces of information: the `Mimetype`, e.g. `application/json`, which helps you determine how to parse the `Data` and the `Type`, a user defined schema that can be used to validate or verify the event once parsed. For more on types and mimetypes, see the [Ensign documentation](https://ensign.rotational.dev).\n\n### Publishing Events\n\nTo publish an event to a topic, you create an event, and then use the clients, `Publish` method as follows:\n\n```go\nvar client *ensign.Client\n\nfunc publishMessages() {\n\tfor i := 0; i \u003c 100; i++ {\n\t\t// Create a simple event\n\t\tmsg := \u0026ensign.Event{Data: []byte(fmt.Sprintf(\"event no. %d\", i+1))}}\n\n\t\t// Publish the event\n\t\tif err := client.Publish(\"example-topic\", msg); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\t// Determine if the event was published or not\n\t\tif _, err := msg.Nacked(); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\ttime.Sleep(time.Second)\n\t}\n}\n```\n\nWhen publishing events you can check if the event was acked (sucessfully published) or nacked (there was an error during publishing) using the `Acked()` and `Nacked()` methods of the `Event` that you created.\n\n### Subscribing\n\nTo subscribe to events on a topic or topics, you can create an object with a channel to receive events on.\n\n```go\nvar client *ensign.Client\n\nfunc subscribeEvents() {\n\tsub, err := client.Subscribe(\"example-topic-a\", \"example-topic-b\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfor event := range sub.C {\n\t\tif err := handleEvent(event); err != nil {\n\t\t\tevent.Nack(api.Nack_UNPROCESSED)\n\t\t} else {\n\t\t\tevent.Ack()\n\t\t}\n\t}\n}\n\nfunc handleEvent(event *ensign.Event) error {\n\t// handle each event as it comes in.\n}\n```\n\nIt is important to let Ensign know if the event was processed successfully using the `Ack` and `Nack` methods on the event -- this will help Ensign determine if it needs to resend the event or not.\n\n## Quick API Reference\n\n- [`New`](https://pkg.go.dev/github.com/rotationalio/go-ensign#New): create a new Ensign client with credentials from the environment or from a file.\n- [`Event`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Event): the event data structure for publishing and subscribing.\n- [`client.Publish`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Client.Publish): publish one or more events to a specified topic.\n- [`client.Subscribe`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Client.Subscribe): create a `Subscription` with a channel to receive incoming events on.\n- [`Subscription`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Subscription): the object return from a `Subscribe` operation, with an events channel, `C` to listen for events on.\n- [`client.TopicExists`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Client.TopicExists): check if a topic with the specified name exists in the project.\n- [`client.CreateTopic`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Client.CreateTopic): create a topic with the specified name in the project.\n- [`client.ListTopics`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Client.ListTopics): list all the topics in the project.\n- [`client.TopicID`](https://pkg.go.dev/github.com/rotationalio/go-ensign#Client.TopicID): get the topic ID from a topic name.\n- [`cache.Get`](https://pkg.go.dev/github.com/rotationalio/go-ensign/topics#Cache.Get): get a topic ID from a topic name.\n- [`cache.Exists`](https://pkg.go.dev/github.com/rotationalio/go-ensign/topics#Cache.Exists): check if the specified topic exists.\n- [`cache.Ensure`](https://pkg.go.dev/github.com/rotationalio/go-ensign/topics#Cache.Ensure): a helper for \"create topic if it doesn't exist\".\n- [`cache.Clear`](https://pkg.go.dev/github.com/rotationalio/go-ensign/topics#Cache.Clear): empty the internal cache to fetch data from ensign again.\n- [`cache.Length`](https://pkg.go.dev/github.com/rotationalio/go-ensign/topics#Cache.Length): returns the number of items in the topic cache.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frotationalio%2Fgo-ensign","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frotationalio%2Fgo-ensign","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frotationalio%2Fgo-ensign/lists"}