This is the first part of a microservices development series. The service will consist of the bellow architecture, where we will expose an image optimizer service that will forward the request to a RabbitMQ queue and answer with the bytecode of the optimized image. It shouldn't be a long series so let's see what we can do.

Service architecture

Let's get our environment working. First, we'll need to install the libraries that we'll use.

Create a dir and initialize the nodejs application inside it (npm init) and then let's install the deps.

  • amqplib - AMQP lib to interact with rabbitmq
  • express - Do our basic rest API
  • express-fileupload - easy file upload parser
  • imagemin and imagemin-pngquant - our image compacter
npm install --save express amqplib express-fileupload imagemin imagemin-pngquant

Now let's write the entry points for our service, we'll have two basic entry points. The path / that will have a welcome message, the second path will be /upload and this is the one that will handle the image and produce a job for our workers.

const express = require('express');
const fileUpload = require('express-fileupload');

//Instantiate the app and set the fileupload parser to manage files
const app = express();
app.use(fileUpload());

//Our index entry point
app.get('/', (req, res) => res.send('Hello From ImageCompacter service'));

//The path that will handle the image file and throw them to the queue
app.post('/upload', (req, res) => {
    //With express-fileupload we can grab the files like this
    let img = req.files.image; //"image" is the name of the input

    res.send('Not ready yet');
});

//Finally start the app with the given port number
app.listen(4000, () => console.log('Example app listening on port 4000!'));

Let's check if it works, run the service with node.

node index.js
Example app listening on port 4000!

Open the browser and check if it prints our hello message when accessing localhost:4000. Works? Greate. Now let's work with the image and see how we do it. To optimize our image, we'll use the library imagemin and imagemin-pngquant, it will be that simple for now, we'll work with rabbitmq latter.

const imagemin = require('imagemin');
const imageminPngquant = require('imagemin-pngquant');
//...

//The path that will handle the image file and throw them to the queue
app.post('/upload', (req, res) => {
    let img = req.files.image; //"image" is the name of the input

            imagemin.buffer(img.data, {
        plugins: [imageminPngquant()]
    })
    .then(out => {
        res.write(out,'binary');
        res.end(null, 'binary');
    });
});

    //...

Use Postman to test the request. To see if it will work, make a request to http://localhost:4000/upload with a formdata with a file. Select the "send and Download" instead of "Send" and you should have an image after that. Bellow an image of how your postman should be.

Postman

That's it for today, next week we'll change our code to use RabbitMQ.


Translations: