DEV Community

Cover image for Node Project Skeleton Part II: Anatomy
JTK
JTK

Posted on

Node Project Skeleton Part II: Anatomy

Overview

In this post we are going to go over the function and purpose of different elements of my node application boilerplate structure.

To run the application, you will need some data in MongoDB as discussed in the first post of this series. If you didn't catch that, run back to do that part, or else you can follow along just without running the application.

As also noted in the first post, we will be working off this repo so grab it if you haven't already.

Node project skeleton components

I'm briefly going to talk about the different things that make up this project. This is definitely a minimal project structure. It could be more complicated.

For the reasons I want this project skeleton, simpler is better. I want it to serve as a very lightweight starting point.

The basic top level structure of the project looks as follows:

directory structure

  • db/ contains our MongoDB middleware for NodeJS, a handy driver that is going to allow our server side code to perform database commands.
  • routes/ directory contains a file for each endpoint, with logic for GET/POST/PATCH/etc within.
  • test/ directory contains both our unit and integration tests, and when we run the test suite it looks for a directory with the name test and recursively runs everything within
  • utils/ is a little bit contrived in this example so that we'd have something worth unit testing. In a normal application this is where I have miscellaneous logic and helper functions
  • server.js at the top level is the glue that binds our application together, connecting the database client for Mongo and the routes to the Express app instance, and starting it running on port 3000
  • package.json contains the different npm packages required to run this project, and it also has scripts to run the project as normal (npm run start) and to run the test suite (npm run test)

Project elements: routes

For the work we will be doing on this app, we have two main resources: equipment, and pokemon. Each resource will have a route file with all the logic needed to perform read and write operations on those resources.

Below, you can see the basic skeleton of a route file. The structure is pretty uniform, router.<HTTP verb>, with logic within. We will be authoring full logic for a route in the next post.

// routes/equipment.js

router.get("/", async (req, res) => {
  /* Do stuff */
});

router.post("/", async (req, res) => {
  /* Do stuff */
});

router.patch("/:id", async (req, res) => {
  /* Do stuff */
});

router.delete("/:id", async (req, res) => {
  /* Do stuff */
});
Enter fullscreen mode Exit fullscreen mode

Project elements: mongo commands

There is a lot more to get into here than we will explore, but we are going to make good use of MongoDB commands to work with our data set. If you have a relational database background and haven't worked with mongo before, all you really need to know is that it isn't difficult to find mongo counterparts to most constructs and capabilities in SQL.

Below you can see a few examples from the MongoDB docs of conversion guides between SQL/Mongo.

SQL/Mongo conversion chart

Project Elements: Mocha/Chai Testing Toolkit

This guide is a whirlwind tour of the NodeJS ecosystem, but this is a brief guide to some of the functionality we will use in our tests.

  • describe() is used as a high level function wrapper with descriptive text for a group of tests
  • it() is a lower level wrapper in a grouping of tests that describes the output of a specific test
  • assert() is, naturally, an assertion call for what our tests expect to be true. It can accept various types of expression
  • equals() measures equality between items
  • includes() can be used to confirm a substring in string, or item in array

Up Next

In Part III, we are going to do our own work building some endpoints and tests out. Stay tuned for the conclusion to this series.

Oldest comments (0)