What is the difference between Controllers and Services in Node REST API's?
Tags: javascript, node
Published: 2019-02-12 13:17:00

---
title: What is the difference between Controllers and Services in Node REST API's?
published: true
tags: javascript,nodejs
canonical_url: https://www.coreycleary.me/what-is-the-difference-between-controllers-and-services-in-node-rest-apis/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/an6u2rbhcqyas7671i4w.png
---
<em><strong>Originally published at <a href="https://www.coreycleary.me/what-is-the-difference-between-controllers-and-services-in-node-rest-apis/">coreycleary.me</a></strong>. This is a cross-post from my content blog. I publish new content every week or two, and you can <a href="https://www.coreycleary.me/about/">sign up to my newsletter</a> if you'd like to receive my articles directly to your inbox! I also regularly send cheatsheets and other freebies.</em>

If you've built out a REST API in Node (or other languages, for that matter), you've likely used the concept of "controllers" to help organize your application. Maybe you put your calls to your database or models there, called some other endpoints, and added some business logic to process the returns.

That controller is something that probably looks like this:

```javascript
const registerUser = async (req, res, next) => {
  const {userName, userEmail} = req.body
  try {
    // add user to database
    const client = new Client(getConnection())
    await client.connect()

    await client.query(`INSERT INTO users (userName) VALUES ('${userName}');`)
    await client.end()

    // send registration confirmation email to user
    const ses = new aws.SES()

    const params = { 
      Source: sender, 
      Destination: { 
        ToAddresses: [
          `${userEmail}` 
        ],
      },
      Message: {
      Subject: {
        Data: subject,
        Charset: charset
      },
      Body: {
        Text: {
          Data: body_text,
          Charset: charset 
        },
        Html: {
          Data: body_html,
          Charset: charset
        }
      }
    }

    await ses.sendEmail(params) 
    
    res.sendStatus(201)
    next()
  } catch(e) {
    console.log(e.message)
    res.sendStatus(500) && next(error)
  }
}
```

But what you might not have used as much, or even heard of, is the concept of "services". Or maybe you have heard of the concept and heard that you should be using them, but are questioning what logic goes there compared to what goes in your controllers.

Using services in API's is something I don't often see in Node-land, but is such a powerful addition to the structure of your API that will make it much easier for testing, code organization, and code re-use.

So if they are such a helpful way of structuring your API, what exactly <em>are</em> <strong>services</strong>?

In order to answer this question, we'll go into <strong>what the differences between controllers and services are</strong> and <strong>what goes where</strong> so you can more properly structure your Node API's.

<h3>A Manager / Worker analogy</h3>
One of the most helpful ways I can think of to explain the differences between the two is by using an analogy from the business world - the "manager" / "worker" dichotomy. We'll be using simplified stereotypes of what a manager does and what a worker does - I'm in no way saying that all managers have one type of role and workers have another!

In our analogy, the <strong>controller</strong> is the <strong>manager</strong>, while the <strong>service</strong> is the <strong>worker</strong>.

If you think about what the manager's role is, he/she typically:
<ul>
	<li>manages the incoming work requests</li>
	<li>decides which worker should do the work</li>
	<li>splits up the work into sizable units</li>
	<li>passes that work off</li>
	<li>if the work requires multiple people working on multiple things, orchestrates the work</li>
	<li>but does not <strong>do</strong> the work himself/herself (again, using a basic stereotype here!)</li></ul>

And, a worker typically:
<ul>
	<li>receives the request from the manager</li>
	<li>figures out the individual details involved in completing the request</li>
	<li>is generally only concerned with the tasks he/she has to complete</li>
	<li>not responsible for making decisions about the "bigger" picture</li>
	<li>does the actual work necessary to complete the tasks/request</li>
	<li>returns the completed work to the manager</li>
</ul>

The overarching theme here is that the <strong>manager/controller</strong> receives the work, decides who should do it, then passes off the request to be completed. While the <strong>worker/service</strong> is the one that takes that request and actually completes it. And you maybe have multiple workers working on different requests/tasks that complete the bigger picture, which the manager joins together so it makes sense.

<h3>What logic goes where?</h3>
Using this analogy, let's look at controllers vs. service from a technical perspective:

A controller:
<ul>
	<li>manages the incoming <del>work</del> HTTP requests</li>
	<li>decides <del>which worker</del> what service should do the work</li>
	<li>splits up the work into sizable units</li>
	<li>passes <del>that work</del> the necessary data from the HTTP requests off to the service(s)</li>
	<li>if the work requires multiple <del>people</del> services working on multiple things, orchestrates <del>the work</del> those service calls</li>
	<li>but does not <strong>do</strong> the work himself/herself <del>(again, using a basic stereotype here!)</del> (not a stereotype here, the controller shouldn't be doing the work)</li></ul>

To sum up the above, the controller <a href="https://www.coreycleary.me/why-you-should-isolate-express-from-the-rest-of-your-node-application/" rel="noopener" target="_blank">takes what it needs from Express</a> (or whatever framework you're using), does some checking/validation to figure out to which service(s) should the data from the request be sent to, and orchestrates those service calls.

So there is <em>some</em> logic in the controller, but it is not the business logic/algorithms/database calls/etc that the services take care of. Again, the controller is a manager/supervisor.

And a service:
<ul>
	<li>receives the <del>request</del> data it needs from the manager in order to perform its tasks</li>
	<li>figures out the <del>individual details</del> algorithms/business logic/database calls/etc involved in completing the request</li>
	<li>is generally only concerned with the tasks he/she has to complete</li>
	<li>not responsible for <del>making decisions about the "bigger" picture</del> orchestrating the different service calls</li>
	<li>does the actual work necessary to complete the tasks/request</li>
	<li>returns <del>the completed work</del> a response to the manager</li>
</ul>

Now summing up the service, the service is responsible for getting the work done and returning it to the controller. It contains the business logic that is necessary to actually meet the requirements and return what the consumer of the API is requesting.

<h3>A note on what is meant by "business logic"</h3>
I like to think of business logic as the more "pure" form of logic. It is logic that doesn't (usually!) care about validating the request or handling anything framework-specific. It just handles algorithms/rules for processing data, storing of data, fetching data, formatting that data, etc. These rules are usually determined by business requirements.

For example, if you had an API that returned how many users had been registered on your platform within the last X amount of days, the business logic here would be querying the database and doing any formatting of that data before it returned it to the controller.

<h3>Example of controller and service separation</h3>
Let's refactor our original controller-only code to look at an example of what this separation of concerns between controllers and services might look like:

First we'll pull out the logic for adding the user into a service.

Registration service:
```javascript
const addUser = async (userName) => {
  const client = new Client(getConnection())
  await client.connect()
  
  await client.query(`INSERT INTO users (userName) VALUES ('${userName}');`)
  await client.end()
}

module.exports = {
  addUser
}
```
Next we'll pull out the logic for sending a registration email to the user.

Email service:
```javascript
const ses = new aws.SES()

const sendEmail = async (userEmail) => {
  const params = { 
    Source: sender, 
    Destination: { 
      ToAddresses: [
        `${userEmail}`
      ],
    },
    Message: {
      Subject: {
        Data: subject,
        Charset: charset
      },
      Body: {
        Text: {
          Data: body_text,
          Charset: charset 
        },
        Html: {
          Data: body_html,
          Charset: charset
        }
      }
    }
  }
  
  await ses.sendEmail(params) 
}

module.exports = {
  sendEmail
}
```
And finally, we'll greatly simplify the controller to simply make these two service calls:
```javascript
const {addUser} = require('./registration-service')
const {sendEmail} = require('./email-service')

const registerUser = async (req, res, next) => {
  const {userName, userEmail} = req.body
  try {
    // add user to database
    await addUser(userName)

    // send registration confirmation email to user
    await sendEmail(userEmail)
    
    res.sendStatus(201)
    next()
  } catch(e) {
    console.log(e.message)
    res.sendStatus(500) && next(error)
  }
}

module.exports = {
  registerUser
}
```

<h3>In summary</h3>
That about wraps it up. Hopefully now you have a better understanding of what logic goes in a controller vs. what goes in the service. The easy way of remembering it is:
<ul>
	<li>controller: managers/orchestrates the work</li>
	<li>service: executes the work</li>
</ul>

Separating like this becomes a powerful tool for code reuse and code organization. Try it out with the next REST API you're building and I think you'll find it helps a lot.

I'm writing a lot of new content to help make Node and JavaScript easier to understand. Easier, because I don't think it needs to be as complex as it is sometimes. If you enjoyed this post and found it helpful <a href="https://www.coreycleary.me/about/">here's that link again</a> to subscribe to my newsletter!