I have a go
service that publishes a message to rabbitmq
and the code which is responsible for that part is as below:
package main
import (
"log"
"github.com/streadway/amqp"
)
func main() {
conn, amqError := amqp.Dial("amqp://localhost:5672/")
if amqError != nil {
panic(amqError)
}
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
q, err := ch.QueueDeclare(
"default", // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue")
body := "{ \"body\":\"Hello...\", \"pattern\":\"test\", \"age\":\"20\"}"
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body),
},
)
failOnError(err, "Failed to publish a message")
}
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
And the Nestjs
part that is consuming the message is as:
import { Controller } from '@nestjs/common';
import { Ctx, EventPattern, Payload, RmqContext } from '@nestjs/microservices';
@Controller()
export class AppController {
constructor() { }
@EventPattern("test")
getEventMessage(@Payload() data: any, @Ctx() context: RmqContext) {
console.log("data is -> ", data) // always undefined
console.log(
"content of message is -> ",
JSON.parse(
context.getMessage().content.toString() // from buffer to string
)
)
}
}
Now the problem is that I can't get the message from data instead of parsing it from ctx
, also I need to send the message in go as json
without skipping double quotes like this "\""
CodePudding user response:
The following is the response to your questions:
- In the examples of NextJS they don't provide how to use the payload data, instead of it, they say:
To access the original RabbitMQ message (with the properties, fields, and content), use the getMessage() method of the RmqContext
Given the above statement, you are parsing properly the message in the queue.
- Avoiding to do manually the body string to send, you should use a process called json Marhsal of struct, for example:
- You should create a struct that contains the information to send to queue
- Marshal struct and generates the
[]byte
type MessageQueue struct {
Body string `json:"body"`
Pattern string `json:"pattern"`
Age string `json:"age"`
Data string `json:"data"`
}
func NewMessageQueue(body, pattern, age string, data) *MessageQueue {
return &MessageQueue{
body, pattern, age, data
}
}
func (m *MessageQueue) Marshal() ([]byte, error) {
bytes, err := json.Marshal(m)
if err != nil {
return nil, err
}
return bytes, err
}
func main() {
...
message := NewMessageQueue("Hello...", "test", "20", "data...")
// TODO: check the error
body, _ := message.Marshal()
err = ch.Publish(
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
Body: body,
},
)
...
}
Update:
- The
data
param received by controller ongetEventMessage
method, it should be sent on body from Golang to be deserialized byNestjs
. It means the structure should be the following:
type MessageQueue struct {
Body string `json:"body"`
Pattern string `json:"pattern"`
Age string `json:"age"`
Data string `json:"data"`
}