-
Let me first introduce about the solution that I'm implementing here and some requisites that you need to archive if you want to run this lab in your local environment.
- You need Docker Engine installed
- You need NodeJS installed
-
All files used for this labs are public available in GitHub Gist clone this repository. Once cloned, access to this repository.
$ git clone https://gist.github.com/8d32c1c164e6d881b8299f3c49857cbf.git
-
For Message Queue we are using RabbitMQ, let's install using the official docker image
$ sudo docker run -d --hostname rabbit -p 5672:5672 -p 15672:15672 --name rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password rabbitmq:3-management
-
We have created a very simple HTML Contact Form where you can fill with your Name, Email and Phone. You don't need to run a web server, just open the HTML file in your browser.
$ firefox form.html
-
Right now this Contact Form only collect data but no serverless function is listen to so we need to install and run it. If you already have NodeJS installed in your computer, please execute
$ npm install
$ npx functions-framework --target=contact-form
-
Great! You have a serverless function working in your local environment or you can publish it to any, not limited to GCP, public cloud provider like AWS or Azure. I'm using Google Functions Framework to avoid extra NodeJS Server configurations that aren't important in this Lab.
-
This serverless function is listen in your localhost and also your Contact Form is configured to POST new data to the same address.
-
Let's create some posts and see what happened in RabbitMQ using user:password as credentials
$ firefox http://localhost:15672
-
Excellent! There are some messages in the queue. Now, we need a worker that consume these messages.
$ node worker.js
-
All messages in the queue are consumed by the worker.
Last active
August 23, 2024 13:04
-
-
Save giacchetta/8d32c1c164e6d881b8299f3c49857cbf to your computer and use it in GitHub Desktop.
Contact Form with RabbitMQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
form.form-example { | |
display: table; | |
} | |
div.form-example { | |
display: table-row; | |
} | |
label,input { | |
display: table-cell; | |
margin-bottom: 10px; | |
} | |
label { | |
padding-right: 10px; | |
} | |
</style> | |
<form action="http://localhost:8080" method="POST" class="form-example"> | |
<div class="form-example"> | |
<label for="name">Enter your name: </label> | |
<input type="text" name="name" id="name" required /> | |
</div> | |
<div class="form-example"> | |
<label for="email">Enter your email: </label> | |
<input type="email" name="email" id="email" required /> | |
</div> | |
<div class="form-example"> | |
<label for="phone">Enter your phone: </label> | |
<input type="phone" name="phone" id="phone" required /> | |
</div> | |
<div class="form-example"> | |
<input type="submit" value="Subscribe!" /> | |
</div> | |
</form> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const functions = require('@google-cloud/functions-framework'); | |
var amqp = require('amqplib/callback_api'); | |
functions.http('contact-form', (req, res) => { | |
amqp.connect('amqp://user:password@localhost', function(error0, connection) { | |
if (error0) { | |
throw error0; | |
} | |
connection.createChannel(function(error1, channel) { | |
if (error1) { | |
throw error1; | |
} | |
var data = { | |
'name': req.body.name, | |
'email': req.body.email, | |
'phone': req.body.phone | |
}; | |
const exchange = 'contact-form'; | |
const queue = exchange + '-queue' | |
channel.assertExchange(exchange, 'fanout', { durable: true }); | |
channel.assertQueue(queue, { durable: true }); | |
channel.bindQueue(queue, exchange, ''); | |
// Convert data to string before publish | |
channel.publish(exchange, '', Buffer.from(JSON.stringify(data)),{ persistent: true }); | |
console.log(data); | |
}); | |
}); | |
res.sendStatus(200); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"dependencies": { | |
"@google-cloud/functions-framework": "^3.4.2", | |
"amqplib": "^0.10.4" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var amqp = require('amqplib/callback_api'); | |
amqp.connect('amqp://user:password@localhost', function(error0, connection) { | |
if (error0) { | |
throw error0; | |
} | |
connection.createChannel(function(error1, channel) { | |
if (error1) { | |
throw error1; | |
} | |
const exchange = 'contact-form'; | |
const queue = exchange + '-queue'; | |
channel.consume(queue, function(msg) { | |
if(msg.content) { | |
data = JSON.parse(msg.content); // Convert back to an object | |
console.log('Your name:', data.name); | |
console.log('Your email:', data.email); | |
console.log('Your phone:', data.phone); | |
channel.ack(msg); // ack rabbit you finished your work | |
} | |
}, { | |
noAck: false | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment