go-rabbitmq

Golang AMQP wrapper for RabbitMQ with better API

Background

In Golang, to use RabbitMQ with AMQP has advantages, especially in messaging systems.
It's done with the AMQP connector.
But, the problem is it has a less convenient API.
Programmers have to write something that should be set by default.
For example, when creating a queue on RabbitMQ.
We have to do this.

q, err := ch.QueueDeclare(
  "hello", // name
  false,   // durable
  false,   // delete when unused
  false,   // exclusive
  false,   // no-wait
  nil,     // arguments
)
failOnError(err, "Failed to declare a queue")

Too many false in there, which should be set as the default value.

By using this module, we can do same think with less code. See above.

q, err := mq.DeclareQueue(rabbitmq.NewQueueOptions().SetName("hello"))
failOnError(err, "Failed to declare a queue")

No need to write false, because it is the default value.

So, to conclude, this module makes it easy to use amqp for rabbitmq.

Features

  • Built on top of famous AMQP connector in Go.
  • All object reference like connection, channel, queue, etc are original by the AMQP connector (no monkey patch or any modifications).
  • It has construction API and API with builder pattern.
  • Does not modify incoming messages, so it can be controlled manually.
  • Reuse connection to create MQ stuff.

Usage

Installation

Inside terminal emulator, simply run command below.

go get github.com/hadihammurabi/go-rabbitmq

After installation it can be imported into any Go project.
For example.

package main

import (
 rabbitmq "github.com/hadihammurabi/go-rabbitmq"
)

Connect to RabbitMQ

It can do as below.

mq, err := rabbitmq.NewMQ("amqp://guest:[email protected]:5672/")
if err != nil {
 log.Fatal(err)
}

// don't forget to close the connection and channel
defer mq.Close()

Declare Queue

Queue declaration can be done like this, after connecting to mq of course.

It only connects to the queue if the queue exists or create one if it doesn't exist. (RabbitMQ behavior)

q, err := mq.DeclareQueue(rabbitmq.NewQueueOptions().SetName("hello"))
if err != nil {
 log.Fatal(err)
}

Declare Exchange

Exchange declaration can be done like this, after connecting to mq of course.

err := mq.DeclareExchange(rabbitmq.NewExchangeOptions().SetName("hello").SetType(rabbitmq.ExchangeTypeFanout))
if err != nil {
 log.Fatal(err)
}

Bind Queue to Exchange

Every message published to exchange will be distributed to every bound queue.
To bind queue with exchange, follow example below.

err := mq.QueueBind(rabbitmq.NewQueueBindOptions().SetName("hello").SetExchange("hello"))
if err != nil {
 log.Fatal(err)
}

Publish a Message

A message can be sent to exchange by mentioning the name exchange.
Publishing a message can do like this.

err := mq.Publish(
  rabbitmq.NewPublishOptions().
        SetExchange("hello").
	SetMessage(amqp.Publishing{
		ContentType: "text/plain",
		Body:        []byte(body),
	}),
)
if err != nil {
 log.Fatal(err)
}

Consume Messages

Every message in the queue can be consumed by the queue consumer.
To consume messages in queue can do like this.

The following code will run forever to listen for new message in queue.

msgs, err := mq.Consume(nil)
if err != nil {
 log.Fatal(err)
}

forever := make(chan bool)
go func() {
  for msg := range msgs {
    fmt.Println(string(msg.Body))
    msg.Ack(false)
  }
}()
<-forever

How It Works

Every AMQP related function call will invoke the AMQP connector function.
For example when creating a new MQ, it will call the AMQP connection function.
Declare queue, declare exchange, publish, consume, etc will do the same.

Please use any references made previously to prevent too many function calls.

GitHub

https://github.com/hadihammurabi/go-rabbitmq