This is a Go AMQP 0.9.1 client wraps amqp091-go with support generics
- Support of the encoding messages
- defaults encoding (json, protobuf, protojson)
- support of custom marshal/unmarshal functions
- Middleware for easy integration
Go version 1.20+
go get github.com/itcomusic/amqpx
package main
import (
"context"
"fmt"
"github.com/itcomusic/amqpx"
)
func main() {
conn, _ := amqpx.Connect()
defer conn.Close()
// simple publisher
pub := amqpx.NewPublisher[[]byte](conn, amqpx.Direct, amqpx.UseRoutingKey("routing_key"))
_ = pub.Publish(amqpx.NewPublishing([]byte("hello")).PersistentMode(), amqpx.SetRoutingKey("override_routing_key"))
// simple consumer
_ = conn.NewConsumer("foo", amqpx.D(func(ctx context.Context, req *amqpx.Delivery[[]byte]) amqpx.Action {
fmt.Printf("received message: %s\n", string(*req.Msg))
return amqpx.Ack
}))
}
Pretty using struct and avoiding boilerplate marhsal/unmarshal. It is strict compared content-type of the message and invalid body is rejected.
conn, _ := amqpx.Connect(
amqpx.UseUnmarshaler(amqpxproto.NewUnmarshaler()), // global unmarshalers
amqpx.UseMarshaler(amqpxproto.NewMarshaler())), // global marshaler
defer conn.Close()
type Gopher struct {
Name string
}
// override default marshaler
pub := amqpx.NewPublisher[Gopher](conn, amqpx.Direct, amqpx.SetMarshaler(amqpxjson.Marshaler))
_ = pub.Publish(amqpx.NewPublishing(Gopher{Name: "Rob"}), amqpx.SetRoutingKey("routing_key"))
// override default unmarshaler
_ = conn.NewConsumer("bar", amqpx.D(func(ctx context.Context, req *amqpx.Delivery[Gopher]) amqpx.Action {
fmt.Printf("user-id: %s, received message: %s\n", req.Req.UserID, req.Msg.Name)
return amqpx.Ack
}), amqpx.SetUnmarshaler(amqpxjson.Unmarshaler), amqpx.SetAutoAckMode())
The Prefetch count informs the server will deliver that many messages to consumers before acknowledgments are received. The Concurrency option limits numbers of goroutines of consumer, depends on prefetch count and auto-ack mode.
// prefetch count
_ = conn.NewConsumer("foo", amqpx.D(func(ctx context.Context, req *amqpx.Delivery[[]byte]) amqpx.Action {
fmt.Printf("received message: %s\n", string(*req.Msg))
return amqpx.Ack
}), amqpx.SetPrefetchCount(8))
// limit goroutines
_ = conn.NewConsumer("foo", amqpx.D(func(ctx context.Context, req *amqpx.Delivery[[]byte]) amqpx.Action {
fmt.Printf("received message: %s\n", string(*req.Body))
return amqpx.Ack
}), amqpx.SetAutoAckMode(), amqpx.SetConcurrency(32))
The declare queue, exchange and binding queue.
_ = conn.NewConsumer("foo", amqpx.D(func(ctx context.Context, req *amqpx.Delivery[[]byte]) amqpx.Action {
fmt.Printf("received message: %s\n", string(*req.Msg))
return amqpx.Ack
}), amqpx.DeclareQueue(amqpx.QueueDeclare{AutoDelete: true}),
amqpx.DeclareExchange(amqpx.ExchangeDeclare{Name: "exchange_name", Type: amqpx.Direct}),
amqpx.BindQueue(amqpx.QueueBind{Exchange: "exchange_name", RoutingKey: []string{"routing_key"}}))
Predefined support opentelemetry using interceptor.
import (
"github.com/itcomusic/amqpx"
"github.com/itcomusic/amqpx/amqpxotel"
)
// global
conn, _ := amqpx.Connect(amqpx.UserInterceptor(amqpxotel.NewInterceptor())
defer conn.Close()
// can use special interceptor for publisher
_ = amqpx.NewPublisher[[]byte](conn, amqpx.Direct, amqpx.SetPublishInterceptor(func(next amqpx.PublisherFunc) amqpx.PublisherFunc {
return func(ctx context.Context, m *amqpx.PublishingRequest) error {
fmt.Printf("message: %s\n", m.Body)
return next(m)
}
}))