{"id":16002809,"url":"https://github.com/soreing/hopper","last_synced_at":"2026-04-24T10:03:43.774Z","repository":{"id":243564141,"uuid":"812643828","full_name":"Soreing/hopper","owner":"Soreing","description":"Golang RabbitMQ wrapper for managing publishers and consumers","archived":false,"fork":false,"pushed_at":"2024-08-10T14:32:09.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-19T20:09:45.708Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Soreing.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}},"created_at":"2024-06-09T13:31:13.000Z","updated_at":"2024-08-10T14:32:12.000Z","dependencies_parsed_at":"2024-06-09T21:57:07.827Z","dependency_job_id":"7cae4d95-edf9-4042-9089-495d0120b1c3","html_url":"https://github.com/Soreing/hopper","commit_stats":null,"previous_names":["soreing/hopper"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Soreing/hopper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Soreing%2Fhopper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Soreing%2Fhopper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Soreing%2Fhopper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Soreing%2Fhopper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Soreing","download_url":"https://codeload.github.com/Soreing/hopper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Soreing%2Fhopper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32218290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T09:47:08.147Z","status":"ssl_error","status_checked_at":"2026-04-24T09:46:41.165Z","response_time":64,"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":"2024-10-08T10:04:12.090Z","updated_at":"2026-04-24T10:03:43.748Z","avatar_url":"https://github.com/Soreing.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hopper\n![Build](https://github.com/soreing/hopper/actions/workflows/build_status.yaml/badge.svg)\n![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Soreing/4b6f950f01f3e6e5b9ed17b268664538/raw/hopper)\n[![Go Report Card](https://goreportcard.com/badge/github.com/Soreing/hopper)](https://goreportcard.com/report/github.com/Soreing/hopper)\n[![Go Reference](https://pkg.go.dev/badge/github.com/Soreing/hopper.svg)](https://pkg.go.dev/github.com/Soreing/hopper)\n\nHopper is a wrapper around the amqp091-go package, providing a simplified and quick \nway to create publishers and consumers on RabbitMQ.\n\n## Controllers\nConnect to the RabbitMQ server by creating a Controller instance with a connection \nURL and configs.\n```golang\nurl := \"amqp://guest:guest@localhost:5672/\"\nctrl, err := hopper.NewController(url, amqp091.Config{})\nif err != nil {\n    panic(err)\n}\n```\n\nThe Controller implements functions that call the internal amqp091.Channel for \ninteracting with exchanges and queues. The below example sets up a simple test\ncase, where a `messages` exchange routes inbound messages to the `inbound` queue.\n\n```golang\nctrl.ExchangeDeclare(\"messages\", \"direct\", true, false, false, false, nil)\nctrl.QueueDeclare(\"inbound\", true, false, false, false, nil)\nctrl.QueueBind(\"inbound\", \"messages.inbound\", \"messages\", false, nil)\n```\n\n## Publishers\nThe Controller can create Publishers, which create their own amqp091.Channel\nand manage the publishing of messages. The publisher needs an Id to distinguish\ndifferent publishers and a mode that sets the behavior of the publisher.\nConfirmMode will make the publisher wait for confirmations from the server,\nand TransactionMode makes publishings atomic until they are either committed or\nrolled back.\n\n```golang\npub, err := ctrl.NewPublisher(\"publisher-id\", hopper.ConfirmMode)\nif err != nil {\n    panic(err)\n}\n```\n\nPublishers support middleware functions that execute on every message that is \nsent with the publisher. The middleware function provides the original context\nof the called function, as well as a PublisherContext, which exposes\nthe amqp091.Publishing object for modification, as well as the exchange \nand routing key.\n\nMiddleware functions execute in the order they were attached. To move to the\nnext function in the publishing pipeline, call .Next() on the publishing context.\n\n```golang\npub.Use(func(ctx context.Context, pctx *hopper.PublishingContext) {\n    pubId := pctx.PublisherId()\n    msgId := \"3e9dc427-a233-4352-878b-808312f7ec48\"\n    pctx.Publishing.MessageId = msgId\n\n    start := time.Now()\n    pctx.Next()\n    elapsed := time.Since(start)\n\n    if err := pctx.GetError(); err == nil {\n        fmt.Println(\"Message\", msgId, \"delivered in\", elapsed, \"by\", pubId)\n    }\n})\n```\n\nPublishing sends a message body with a content type to some exchange with a routing key. \n```golang\nctx := context.TODO()\nmessage := []byte(\"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\")\npublishing := amqp091.Publishing{Body: message, ContentType: \"plain/text\"}\n\n// Publishing synchronously (blocking)\nerr = pub.Publish(ctx, \"messages\", \"messages.inbound\", publishing)\nif err != nil {\n    panic(err)\n}\n\n// Publishing asynchronously (non-blocking)\nchn := pub.PublishAsync(ctx, \"messages\", \"messages.inbound\", publishing)\nerr \u003c- chn\nif err != nil {\n    panic(err)\n}\n```\n\n## Consumers\nThe Controller can create Consumers, which create their own amqp091.Channel\nand manage the consuming of messages. The consumer needs an Id to distinguish\ndifferent consumers and a consumer channel to declare the queue with bindings.\n\n```golang\nqueue := hopper.ConsumerQueue{\n    Name:    \"inbound\",\n    Durable: true,\n    AutoAck: false,\n    Bindings: map[string][]string{\n        \"messages\": {\"messages.inbound\"},\n    },\n}\n\ncon, err := ctrl.NewConsumer(\"consumer-id\", queue)\nif err != nil {\n    panic(err)\n}\n```\n\nTo consume messages, get the amqp091.Delivery channel from the consumer. You can\nacknowledge or reject messages directly on the amqp091.Delivery or on the consumer\nwith the delivery tag.\n```golang\nmsg := \u003c-con.Deliveries()\nfmt.Println(string(msg.Body))\nmsg.Ack(false)\n```\n\n## Termination\nControllers, Publishers and Consumers include a Done() method, returning a \nchannel that closes when the entities are closed. When encountering an error,\nthe entities close automatically and the error can be fetched with the Error()\nmethod. To gracefully shut down the entities, call Shutdown().\n```golang\ngo func(con *hopper.Consumer) {\n    \u003c-con.Done()\n    if err := con.Error(); err != nil {\n        fmt.Println(\"Consumer terminated with error:\", err)\n    }\n}(con)\n\ncon.Shutdown(ctx)\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoreing%2Fhopper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoreing%2Fhopper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoreing%2Fhopper/lists"}