{"id":31601753,"url":"https://github.com/pitabwire/natspubsub","last_synced_at":"2026-03-07T17:01:02.377Z","repository":{"id":196834433,"uuid":"696432009","full_name":"pitabwire/natspubsub","owner":"pitabwire","description":"A go-cloud pubsub plugin for nats io jetstream.","archived":false,"fork":false,"pushed_at":"2026-03-02T12:21:28.000Z","size":439,"stargazers_count":3,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-02T16:20:28.452Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pitabwire.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-09-25T18:21:45.000Z","updated_at":"2026-03-02T12:21:30.000Z","dependencies_parsed_at":"2023-10-16T21:07:46.089Z","dependency_job_id":"9f96d37a-7ad6-4c5b-8214-40d2e8000e29","html_url":"https://github.com/pitabwire/natspubsub","commit_stats":null,"previous_names":["pitabwire/jetstreampubsub"],"tags_count":47,"template":false,"template_full_name":null,"purl":"pkg:github/pitabwire/natspubsub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitabwire%2Fnatspubsub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitabwire%2Fnatspubsub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitabwire%2Fnatspubsub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitabwire%2Fnatspubsub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pitabwire","download_url":"https://codeload.github.com/pitabwire/natspubsub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitabwire%2Fnatspubsub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30222338,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T14:02:48.375Z","status":"ssl_error","status_checked_at":"2026-03-07T14:02:43.192Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-10-06T07:59:20.660Z","updated_at":"2026-03-07T17:01:02.370Z","avatar_url":"https://github.com/pitabwire.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# natspubsub\nA go-cloud pubsub plugin for nats io supporting jetstream as well.\n\n[![Tests](https://github.com/pitabwire/natspubsub/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/pitabwire/natspubsub/actions/workflows/tests.yml) \n\n\nPackage natspubsub provides a pubsub implementation for NATS.io and Jetstream. \nUse OpenTopic to construct a *pubsub.Topic, and/or OpenSubscription to construct a\n*pubsub.Subscription. This package uses gob to encode and decode driver.Message to\n[]byte.\n\n# Usage (publishing a message)\n\n```go\n\n    // opening a topic looks like this\n\tpackage main \n    import (\n        \"context\"\n    \n        \"gocloud.dev/pubsub\"\n        _ \"github.com/pitabwire/natspubsub\"\n    )\n\t...\n\tctx := context.Background()\n    // pubsub.OpenTopic creates a *pubsub.Topic from a URL.\n    // This URL will Dial the NATS server at the URL in the environment variable\n    // NATS_SERVER_URL and send messages with subject \"example.mysubject\".\n    topic, err := pubsub.OpenTopic(ctx, \"nats://localhost:4222?jetstream=true\u0026stream_name=example\u0026subject=example.mysubject\")\n    if err != nil {\n        return err\n    }\n\tdefer topic.Shutdown(ctx)\n\t\n    err := topic.Send(ctx, \u0026pubsub.Message{\n        Body: []byte(\"Hello, World!\\n\"),\n        Metadata: map[string]string{\n            \"language\":   \"en\",\n            \"importance\": \"high\",\n        },\n    })\n    if err != nil {\n    return err\n    }\n    \n    \n```\n\n# (receiving messages)\n\n```go\npackage main\nimport (\n    \"context\"\n\n    \"gocloud.dev/pubsub\"\n    _ \"github.com/pitabwire/natspubsub\"\n)\n...\nctx := context.Background()\nsubs, err := pubsub.OpenSubscription(ctx, \"nats://localhost:4222?jetstream=true\u0026stream_name=example\u0026subject=example.mysubject\")\nif err != nil {\n    return fmt.Errorf(\"could not open topic subscription: %v\", err)\n}\n\n// Loop on received messages.\nfor {\n    msg, err := subs.Receive(ctx)\n    if err != nil {\n        // Errors from Receive indicate that Receive will no longer succeed.\n        log.Printf(\"Receiving message: %v\", err)\n        break\n    }\n    // Do work based on the message, for example:\n    fmt.Printf(\"Got message: %q\\n\", msg.Body)\n    // Messages must always be acknowledged with Ack.\n    msg.Ack()\n}\n\ndefer subs.Shutdown(ctx)\n\n\n```\n\n\n# URLs\n\nFor pubsub.OpenTopic and pubsub.OpenSubscription, natspubsub registers\nfor the scheme \"nats\". \n\nThe default URL opener will connect to a default server based on the\nenvironment variable \"NATS_SERVER_URL\".\n\nAuthentication can be configured using the environment variable \"NATS_CREDENTIALS_FILE\".\nIf this variable is set to a path to a NATS credentials file, the client will automatically\nuse those credentials for authentication when connecting to the NATS server.\n\nThis implementation supports all versions of NATS Servers, we however recommend version 2.2.0 or later.\nMessages can be encoded using native NATS message headers, and native message content\nproviding full support for non-Go clients. Operating in this manner is  more \nefficient than using gob.Encoder. Using older versions of the server will result in \nerrors and untested scenarios. \n\nIn the event the user cannot upgrade the nats server, we recommend the use of \nthe in tree implementation instead: https://github.com/google/go-cloud/tree/master/pubsub/natspubsub\n\nTo customize the URL opener, or for more details on the URL format,\nsee URLOpener.\nSee https://gocloud.dev/concepts/urls/ for background information.\n\nExample URLs:\n\n    Topic open - nats://127.0.0.1:4222?jetstream=true\u0026stream_name=testq\u0026stream_retention=workqueue\u0026stream_storage=memory\u0026stream_subjects=testq.*\u0026subject=testq\n   \n    Topic subscription - nats://127.0.0.1:4222?consumer_ack_policy=explicit\u0026consumer_ack_wait=10s\u0026consumer_deliver_policy=all\u0026consumer_durable_name=durabletest\u0026consumer_filter_subject=testq.*\u0026jetstream=true\u0026stream_name=testq\u0026stream_retention=workqueue\u0026stream_storage=memory\u0026stream_subjects=testq.*\n\nThis driver also has a hidden super power to make dynamic publishes from the header content supplied.\nOne just needs to set the header that should be checked to extend the existing topic subject during publishing:\n\n - **header_to_extended_subject**\n\n# Message Delivery Semantics\n\nNATS supports :\nSee https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery\nfor more background.\n\n  1. at-most-once-semantics; applications need not call Message.Ack, applications must also\n       not call Message.Nack. \n\n  2. at-least-once-semantics; this mode is possible with jetstream enabled. \n     applications are supposed to call Message.Ack to remove processed messages from the stream.\n     Enabling this the jetstream mode requires adding the jetstream parameter in the url query.\n\n\n# Subscription options\n\nAll the subscription options are passed in as query parameters to the nats url supplied.\n\nComprehensive definitions of the options can be found below. These are based on the official NATS JetStream configuration from:\n  - [NATS JetStream Stream Configuration](https://docs.nats.io/nats-concepts/jetstream/streams)\n  - [NATS JetStream Consumer Configuration](https://docs.nats.io/nats-concepts/jetstream/consumers)\n\n## Basic Options\n\n| Option     | Default value | Description                                                                                                         |\n|------------|---------------|---------------------------------------------------------------------------------------------------------------------|\n| jetstream  | true          | Enables JetStream functionality for at-least-once delivery semantics                                                |\n| subject    |               | A string of characters that form a name which the publisher and subscriber can use to find each other               |\n| receive_wait_timeout    | 5m            | A timeout for the receive operation. If set to 0, the receive operation will block indefinitely until context ends. |\n\n## Stream Configuration Parameters\n\nStream config options are prefixed by \"stream_\" in URL query parameters.\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `stream_name` | string | (required) | The unique name of the stream |\n| `stream_description` | string | | Optional description of the stream |\n| `stream_subjects` | []string | | List of subjects that the stream is listening on (supports wildcards) |\n| `stream_retention` | string | `limits` | Message retention policy: `limits`, `interest`, or `workqueue` |\n| `stream_max_consumers` | int | -1 | Maximum number of consumers allowed for the stream (-1 for unlimited) |\n| `stream_max_msgs` | int64 | -1 | Maximum number of messages the stream will store (-1 for unlimited) |\n| `stream_max_bytes` | int64 | -1 | Maximum total size of messages the stream will store (-1 for unlimited) |\n| `stream_discard` | string | `old` | Policy for handling messages when limits are reached: `old` or `new` |\n| `stream_discard_new_per_subject` | bool | false | Whether to discard new messages per subject when limits are reached |\n| `stream_max_age` | duration | | Maximum age of messages that the stream will retain (e.g., \"24h\") |\n| `stream_max_msgs_per_subject` | int64 | -1 | Maximum number of messages per subject that the stream will retain (-1 for unlimited) |\n| `stream_max_msg_size` | int32 | -1 | Maximum size of any single message in the stream in bytes (-1 for unlimited) |\n| `stream_storage` | string | `file` | Storage backend type: `file` or `memory` |\n| `stream_num_replicas` | int | 1 | Number of replicas to maintain in clustered JetStream (1-5) |\n| `stream_no_ack` | bool | false | Flag to disable acknowledging messages received by this stream |\n| `stream_duplicate_window` | duration | 2m | Duration within which to track duplicate messages |\n| `stream_placement` | object | | Placement constraints for stream (cluster name and/or tags) |\n| `stream_mirror` | object | | Configuration for mirroring another stream |\n| `stream_sources` | []object | | List of streams this stream sources messages from |\n| `stream_sealed` | bool | false | Flag to mark stream as sealed (no new messages or deletion) |\n| `stream_deny_delete` | bool | false | Flag to restrict ability to delete messages via API |\n| `stream_deny_purge` | bool | false | Flag to restrict ability to purge messages via API |\n| `stream_allow_rollup_hdrs` | bool | false | Flag to allow the Nats-Rollup header for stream content replacement |\n| `stream_compression` | string | | Message storage compression algorithm: `none`, `s2`, or `gzip` |\n| `stream_first_seq` | uint64 | 1 | Initial sequence number for the first message in the stream |\n| `stream_subject_transform` | object | | Configuration for transforming subjects on messages |\n| `stream_republish` | object | | Configuration for republishing messages after storing |\n| `stream_allow_direct` | bool | false | Flag to enable direct access to individual messages |\n| `stream_mirror_direct` | bool | false | Flag to enable direct access to messages from origin stream |\n| `stream_consumer_limits` | object | | Limits for consumers on this stream |\n| `stream_metadata` | map | | User-defined metadata key-value pairs for the stream |\n| `stream_allow_msg_ttl` | bool | false | Flag to allow header-initiated per-message TTLs |\n| `stream_subject_delete_marker_ttl` | duration | | Duration for keeping server markers for deletions |\n\n## Consumer Configuration Parameters\n\nConsumer config options are prefixed by \"consumer_\" in URL query parameters.\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `consumer_name` | string | (auto) | Name for the consumer (auto-generated if not provided) |\n| `consumer_durable_name` | string | | Name for durable subscription (persists across reconnects) |\n| `consumer_description` | string | | Optional description of the consumer |\n| `consumer_deliver_policy` | string | `all` | Where to start delivering messages: `all`, `last`, `new`, `by_start_sequence`, `by_start_time` |\n| `consumer_opt_start_seq` | uint64 | | Starting sequence number when deliver policy is `by_start_sequence` |\n| `consumer_opt_start_time` | time | | Starting time when deliver policy is `by_start_time` (RFC3339 format) |\n| `consumer_ack_policy` | string | `explicit` | How messages are acknowledged: `none`, `all`, `explicit` |\n| `consumer_ack_wait` | duration | 30s | How long server waits for acknowledgement before redelivery |\n| `consumer_max_deliver` | int | -1 | Maximum delivery attempts for a message (-1 for unlimited) |\n| `consumer_backoff` | []duration | | Back-off intervals for retrying message delivery (comma separated) |\n| `consumer_filter_subject` | string | | Subject filter to select messages from stream |\n| `consumer_filter_subjects` | []string | | Multiple subject filters to select messages from stream |\n| `consumer_replay_policy` | string | `instant` | Rate at which messages are sent: `instant` or `original` |\n| `consumer_rate_limit_bps` | uint64 | | Maximum rate of message delivery in bits per second |\n| `consumer_sample_freq` | string | | Frequency for sampling acknowledgements (e.g., \"100%\") |\n| `consumer_max_waiting` | int | 512 | Maximum number of pull requests waiting to be fulfilled |\n| `consumer_max_ack_pending` | int | 1000 | Maximum number of unacknowledged messages (-1 for unlimited) |\n| `consumer_headers_only` | bool | false | Flag to deliver only message headers without payload |\n| `consumer_max_batch` | int | | Maximum batch size for a single pull request |\n| `consumer_max_expires` | duration | | Maximum duration a pull request will wait for messages |\n| `consumer_max_bytes` | int | | Maximum total bytes that can be requested in a batch |\n| `consumer_inactive_threshold` | duration | 5s | Duration after which an inactive consumer is cleaned up |\n| `consumer_num_replicas` | int | | Number of replicas for the consumer state (inherits from stream by default) |\n| `consumer_mem_storage` | bool | false | Flag to force consumer to use memory storage |\n| `consumer_metadata` | map | | User-defined metadata key-value pairs for the consumer |\n| `consumer_pause_until` | time | | Timestamp until which the consumer is paused (RFC3339 format) |\n| `consumer_priority_policy` | string | | Priority policy for the consumer: `standard` or `pinned` |\n| `consumer_priority_timeout` | duration | | Time after which client will be unpinned if inactive |\n| `consumer_priority_groups` | []string | | List of priority groups this consumer supports |\n\n## Batch Receive Parameters\n\nBatch receive options control how messages are batched when receiving.\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `receive_batch_max_handlers` | int | 10 | Maximum number of handlers for processing batch receive operations |\n| `receive_batch_min_batch_size` | int | 1 | Minimum number of messages in a batch for batch receive |\n| `receive_batch_max_batch_size` | int | 100 | Maximum number of messages in a batch for batch receive |\n| `receive_batch_max_batch_byte_size` | int | 1048576 | Maximum total byte size of messages in a batch (1MB default) |\n\n## Batch Ack Parameters\n\nBatch ack options control how message acknowledgments are batched.\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `ack_batch_max_handlers` | int | 10 | Maximum number of handlers for processing batch acknowledgement operations |\n| `ack_batch_min_batch_size` | int | 1 | Minimum number of messages in a batch for batch acknowledgement |\n| `ack_batch_max_batch_size` | int | 100 | Maximum number of messages in a batch for batch acknowledgement |\n| `ack_batch_max_batch_byte_size` | int | 1048576 | Maximum total byte size of messages in a batch (1MB default) |\n\n# Publishing options\n     \n| Option | Default value | Description |\n|--------|---------------|-------------|\n| Subject | | An identifier that publishers send messages to subscribers of interest\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpitabwire%2Fnatspubsub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpitabwire%2Fnatspubsub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpitabwire%2Fnatspubsub/lists"}