streadway / amqp

Go client for AMQP 0.9.1
http://godoc.org/github.com/streadway/amqp
BSD 2-Clause "Simplified" License
4.85k stars 620 forks source link

API improvement. Have a more idiomatic go API. #492

Open thothothotho opened 3 years ago

thothothotho commented 3 years ago

That kind of code:

r.channel.Consume(queueName, consumerID, true, false, false, false, nil)

is quite difficult to read. Maybe rabbitmq specialists have no problem parsing this, but I have. And so my colleagues reviewing my code. So I'm writing this:

r.channel.Consume(queueName, consumerID,
        true,  // autoAck
        false, // exclusive
        false, // noLocal
        false, // noWait
        nil)

I really wish I could write that:

r.channel.Do(amqp.Consume{Queue: queueName, Consumer: consumerId, AutoAck: true})

more example

r.channel.Do(amqp.QueueDeclare{Name: "foo", AutoDelete: true})
r.channel.Do(amqp.QueueBind{Name: "foo", Exchange: "blah"})

So, maybe you should expose your implementation as public stuff. Internally, you're doing exactly that:

func (ch *Channel) QueueBind(name, key, exchange string, noWait bool, args Table) error {
    if err := args.Validate(); err != nil {
        return err
    }

    return ch.call(
        &queueBind{
            Queue:      name,
            Exchange:   exchange,
            RoutingKey: key,
            NoWait:     noWait,
            Arguments:  args,
        },
        &queueBindOk{},
    )
}

ch.call(someType) is really the best readable API, please expose it, it's brilliant.

Thanks

thothothotho commented 3 years ago

Other possibilities. To enforce that some parameters are mandatory

r.channel.QueueDeclare("foo", amqp.AutoDelete)

where

type Option func(interface{})

var  AutoDelete Option = func(v interface{}) {
    opts := v.(*queueDeclare)
    opts.AutoDelete = true
}

func (ch *Channel) QueueDeclare(queue string, options Option...) {
     var cmd = queueDeclare{Queue: queue}
     applyOptions(&cmd, options)  // some helper
    ...
}