Fullstack JavaScript Microservice Web App in Minutes

Sergey Kravchenko
May 27 · 5 min read

This article shows how to quickly prototype a web app that consists of the following main architecture components:

  • front-end service: NGINX web server + React.js app.
  • front-end CSS library: Bootstrap.
  • back-end service: Node.js + Express.js.
  • worker service.
  • database: MongoDB.
  • message broker: RabbitMQ.
  • Docker containers.
  • deployment to AWS EC2.
Image for post
Image for post

We’re going to use the SMF framework, which helps generate the boilerplate code, connect the services and deploy them to AWS:

https://github.com/krawa76/smf

The demo app code is available here:

https://github.com/krawa76/smf-test-web-app

Requirements: Node.js and Docker with Docker Compose installed locally.

Create project

Install SMF, create a new project and cd to the project directory:

$ npm install -g sokyra-microservice-factory
$ smf new test-app
$ cd test-app

Add back-end service

$ smf add service back-endSelect service template:
1) Basic worker
2) Back-end (Express.js)
3) Front-end (React.js)
prompt: number: 2

Add MongoDB and RabbitMQ services, and the corresponding Node.js client libraries:

0) exit selection
1) (message broker) RabbitMQ
2) (database) Memcached
3) (database) MongoDB
4) (database) MySQL
5) (database) PostgreSQL
6) (database) Redis
7) (search engine) Elasticsearch
prompt: number: 3Selected clients:
[MongoDB]
Select another client:
0) exit selection
1) (message broker) RabbitMQ
2) (database) Memcached
3) (database) MongoDB
4) (database) MySQL
5) (database) PostgreSQL
6) (database) Redis
7) (search engine) Elasticsearch
prompt: number: 1

Add front-end service

Create the front-end service, point it to the existing back-end one:

$ smf add service front-endSelect service template:
1) Basic worker
2) Back-end (Express.js)
3) Front-end (React.js)
prompt: number: 3Select a back-end service to connect to:
1: demo
2: back-end
prompt: number: 2

Add worker service

Create the worker service, add the RabbitMQ message broker support:

$ smf add service workerSelect service template:
1) Basic worker
2) Back-end (Express.js)
3) Front-end (React.js)
prompt: number: 1==================================================Select third-party services clients that your service "worker" connects to (one at a time),0) exit selection
1) (message broker) RabbitMQ
2) (database) Memcached
3) (database) MongoDB
4) (database) MySQL
5) (database) PostgreSQL
6) (database) Redis
7) (search engine) Elasticsearch
prompt: number: 1

At this point all the boilerplate code modules and config files for the services and Docker stack are ready.

Run app

Let’s start our services and see how they work:

$ smf up

SMF builds Docker images and start containers. When they are running, we can check our web app in a browser:

http://localhost/

http://localhost/kittens

What we see is a React.js / Bootstrap CSS application that receives the data from the back-end service.

We can also check what Docker containers are running behind the scenes:

$ docker ps

Here we see the front-end, back-end, worker, and demo services (added by default and can me removed), as well as MongoDB database and RabbitMQ message broker:

After we’re done with the testing, we can shut down the app (stop the Docker containers):

$ smf down

Project structure

Let’s inspect what we’ve got auto-generated out of the box so far… All the services code lives in one repo:

The other important modules are:

  • smf-stack.json: project config.
  • smf-env.json: environment variables.
  • smf-deploy.json: deployment config.

Back-end structure

The entry point module main.ts does the following:

  • starts the web server.
  • handles the/kittens endpoint.
  • inserts demo data into the database.
  • sends demo messages to the message broker:

Front-end structure

The main modules here are:

  • Dockerfile: builds the service image with NGINX web server embedded.
  • nginx.conf: web server config.
  • ./app folder: React.js application.
  • ./app/src/App.js: main app module with routing.
  • ./app/src/Api.js: API client.
  • ./app/src/pages: Home, Kittens and NotFound pages.
  • ./app/src/components: flash (alerts, errors, etc.) and navigation modules.

Worker structure

The main module shows how to work with shared modules and exchange demo messages with the message broker:

Fetch data from database

So far our back-end API returns the hard-coded demo data, see ./services/back-end/routes/kittens.ts :

Let’s replace this logic with fetching the data from our kittensdb collection:

Start the app again and see the db data on UI:

$ smf up

http://localhost/kittens

Message broker

At this point, the back-end & worker services exchange demo messages using the demo.* RabbitMQ channel. If you need to send some extra asynchronous jobs, you can establish an extra channel:

Develop / debug mode

Back-end: stop the Docker container, prepare SMF debug config:

$ docker stop test-app-back-end
$ smf debug back-end

Then open the project in VSCode and use “Start Debugging” menu (hit F5).

Front-end: start the React app, non-containerized:

$ docker stop test-app-front-end
$ cd services/front-end/app
$ npm start

Deploy

It’s easy to deploy our project to a remote server which has Docker & Docker-Compose installed. If you don’t have one so far, you can create it in Amazon AWS EC2 using the following simple instruction:

https://github.com/krawa76/smf/blob/master/README-provisioner.md

Docker Hub account is also required. You can sign up for free here if it’s missing:

https://hub.docker.com/

Open smf-deploy.json file in the editor and fill in the Docker Hub login/password, host address, and remote machine SSH credentials (ssh key path). Replace the EC2 public host name in BUILD_REACT_APP_API_URL:

Run this command to deploy the project:

$ smf deploy

Ssh to the remote machine and see our microservices running there:

$ ssh -i "/Users/me/.ssh/aws-key.pem" ubuntu@ec2-x-x-x-x.compute1.amazonaws.com$ docker ps
(gives the list of services)

Open the deployed web app in the browser (specify your EC2 host name):

http://ec2-x-x-x-x.compute1.amazonaws.com

Conclusion

Congrats, you have a working prototype of a containerized microservice web app in the cloud!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store