Explore the anatomy of a Node.js microservice application as an implementation of the hand-gesture game rock, paper, scissors.
- [Narrator] The application we'll be working on is a Microservice implementation of the game Rock, Paper, Scissors. There are three services that make up this Microservice application. First is a standard web interface running on port 5000. The second is a games API service running on port 5005. The third service is the players API which runs on port 5010. The services communicate using REST API's and always return JSON.
It also maintains sessions in mysql using the module express sessions. Web handles all form submission handling, and finally, web sends requests to the games and players' services and renders the results. The web service runs on port 5000 and has a few routes. GET on the route shows the latest and pending final games. POST to games creates a new game. GET games by id renders a game. POST to games by id/choice is the form submission handler for player choices.
Similarly, POST to game id join does exactly that. Finally a POST to game id judge determines the result and redirects back to game renderer. Another approach would have been to POST and switch on action form input, but this is more explicit. Now that we know how to interact with web, let's look at the simpler of the two API services, player. The Player Model is exceedingly simple. It consists of an id, an unsigned positive integer, and a lastUpdated date/time field.
I considered both a name and a session id, but decided they were overkill. The Players API has two routes: POST to create a player, and GET to retrieve a player by id. There's no list of players and you can't modify a player, so why over-engineer? A game is a bit more complex. It starts with an id, a unique identifier, an unsigns positive integer. A game also has a lastUpdated field, a date/time of when the record was last updated.
There's an optional player1 and player2id, also an integer. There's also a player1 and 2choice, which are an enum of rock, paper, or scissors. Each game has a state, defaulting to pending or final, through an enum. Finally, there's an optional playerWinnerid. It's technically possible to spread some of these values out across multiple tables, but for readability, this works. The Games Service has a few routes. You can GET to fetch games by criteria, and POST to create a game, then, you can GET a game by id, and PATCH to update it, then POST to judge to determine the outcome.
There's a final route, rules, that sends an array of human-readable rules for the web service to render. To review, the Rock, Paper, Scissors application consists of three services. A web application on port 5000 as the user interface, a games API on port 5005, and a players API on port 5010. The web interface communicates via REST to the games and players API's which then respond in JSON, a clean separation of responsibilities across three services and a brief example of a microservice pattern.
Did you know that some sites have dozens, even hundreds, of microservices? It's an interesting pattern. Alright, so we've got three microservices. How do we run them?
- Building a troubleshooting mindset
- Why measure performance?
- What's a microservice architecture?
- Managing microservices with PM2
- Effective logging strategies
- Debugging Node.js applications
- Benchmarking performance
- Profiling code execution
- Knowing what to optimize