What kind of code belongs in a utils folder in your REST API?

Generally when working on a REST API, you'll need to write some code that's a bit more generic compared to some of your other business logic. For example, a function that converts dates into a certain format.

When you're working on adding this code, you may be wondering where in your project does it go? Could it be considered a utility? Or does it belong with your business/domain logic? Or you may have worked on API's where there's a utils/utilities folder in the project and questioned exactly what kind of code goes in there.

There is a lot of nuance here, so that's what this post is going to examine and answer the above questions.

Generic, reusable functions

A good hint that your code can be considered a utility is if you find yourself reusing that code in more than one place in your REST API. For example, it could be a function that converts milliseconds to minutes and/or seconds, or one that checks two arrays to see if they contain similar items. These are general enough - and reusable enough - that they deserve to go in their own folder. They're generally common logic functions that are not necessarily specific to your business logic or domain, or even a REST API in general.

Think lodash - it has lots of reusable utility functions that are generic enough they don't contain business logic (like handling customer orders, processing of inventory, etc) and are "utility" enough they can be used by hundreds of thousands of applications.

If your code could theoretically apply to your other REST APIs/services, then it probably belongs in a utils folder, and you could even extract it out into its own Node module if you find your utilities are actually being used frequently across projects.

Compared to middleware

Middleware has code that's reusable across many (if not all) HTTP routes. Does that mean that middleware code is utility code?

In a sense it is a different type of utility code. But middleware doesn't belong in the utils/utilities folder and is different than the type of utility code we've been talking about.

You can imagine middleware as its own type of utility since its reusable. But middlware is always dealing with the HTTP context (request and response objects, it takes those as arguments). Thus it should be grouped differently in your REST API, in its own middleware folder.

Code in your utils/utilities folder shouldn't deal with the HTTP context.

Pure functions

Sometimes you will see the advice that utility functions should be "pure" functions, i.e. they don't have any I/O so no database calls, no external network calls, no file system calls, etc. I'm not 100% sure why this advice floats around out there but my guess is because code that fetches data from a database or from an external HTTP is generally using the result of those fetches to drive domain logic. Generally you're fetching from or storing data in the database in your domain layer (Services/Models).

But often you'll have utility functions dealing with the file system, so I think that theory doesn't make much sense anyways.

Even if your utility code has a database call, it doesn't necessarily mean it's domain/business logic. It can be more generic. For example, the code below checks to see if a user name is available for different user types like a normal user, an admin, a manager, etc. It calls the database but it's generic enough it doesn't belong in a single Service or Model, because then we'd have code duplication (the same method across multiple files). In other words this code is utility enough and reusable enough to not be tied to a specific domain type, where the domain in this case is User or Admin. We don't need a duplicated User.doesUserNameAlreadyExist() and an Admin.doesUserNameAlreadyExist().

const doesUserNameAlreadyExist = async (desiredUserName, userType) => {
  return !!(await knex(`${userType}`)
    .returning('name')
    .where('name', desiredUserName))
}

await doesUserNameAlreadyExist('user123', 'User')
await doesUserNameAlreadyExist('admin456', 'Admin')

Summary

As always when working with code there is nuance and not always a perfect answer. But the guidelines above will give you a good 80%/20% guideline for when to put code in a utils folder. You can use the above examination in order to help you make the best decisions for your project.

At a high-level I touched on project structure for REST APIs in this post. But if you want a much more detailed explanation of how I structure my Node REST APIs, sign up below for a post that goes into that and a repo that contains that structure.

Subscribe for the explanation and repo!

No spam ever. Unsubscribe any time.