# SFRA controllers, middleware chains and models

*B2C Commerce Developer Study Guide · Application Development · Last updated November 3, 2026 · https://www.certifyforce.com/study-guide/b2c-commerce-developer/application-development/sfra-controllers-middleware-chains-and-models*

How SFRA routes are registered and chained, how res.render, res.json and setViewData shape the output, when to append or replace an inherited route, and where models, helpers and factories belong in a cartridge.

- Certification: Salesforce B2C Commerce Developer
- Exam section: Application Development
- Study guide: https://www.certifyforce.com/study-guide/b2c-commerce-developer

**Official exam objective:**

> Given a requirement, create and extend the functionality of a JavaScript controller that leverages models, decorators, factories, or helpers following API best practices, and renders a template or returns a JSON response.

## What the exam expects

- Write an SFRA controller that registers routes with `server.get`, `server.post` or `server.use`, chains middleware correctly and exports its routes.
- Choose `res.render`, `res.json` or `res.setViewData` for a response requirement, and predict what the template's pdict contains.
- Extend an inherited route with `server.append`, `server.prepend` or `server.replace`, and decide which is safe when the original calls a third-party system.
- Restrict a route with middleware filters (`get`, `post`, `https`, `include`) and use route events such as `route:BeforeComplete`.
- Place logic in models, helpers and factories in a custom cartridge, require modules in the narrowest scope, and handle error-page constraints.

Key terms: **route** (a `Controller-RouteName` endpoint registered by the server module); **middleware chain** (the functions between the route name and the main function, run in order); **viewData** (the output object that `setViewData` merges into and the template reads as pdict); **model** or ViewModel (code that turns Script API objects into plain JSON for the storefront); **middleware filter** (a provided step that rejects requests that don't match, such as `https`).

## Key facts

| Fact | Detail | Source |
|---|---|---|
| Route registration | `server.exports()` registers `get`, `post` and `use` functions | [SFRA Features and Components](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-sfra-features-and-comps.html) |
| Missing `next()` | The next step in the chain doesn't run | [SFRA Features and Components](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-sfra-features-and-comps.html) |
| Output timing | Template or JSON output is set after every step completes | [SFRA Features and Components](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-sfra-features-and-comps.html) |
| `route:BeforeComplete` | After all middleware, before `route:Complete`; stores submitted data | [SFRA Features and Components](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-sfra-features-and-comps.html) |
| `server.append` | Original chain runs first, then the new step, before rendering | [Customize SFRA](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-customizing-sfra.html) |
| `server.prepend` | Adds middleware ahead of an inherited route's steps | [SFRA Server-side JavaScript: Server](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/sfrajsdoc/js/server/Server.html) |
| Price factory | `getPrice` returns a `TieredPrice`, `RangePrice` or `DefaultPrice` | [SFRA Server-side JavaScript: Global](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/sfrajsdoc/js/server/global.html) |
| Filter mismatch | Error `Params do not match route` | [Customize SFRA](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-customizing-sfra.html) |
| `include` filter | Limits a route to remote includes | [Customize SFRA](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-customizing-sfra.html) |
| `Error.js` default | 410; 404 only without `isslot`, `iscomponent`, `isinclude` | [Controllers](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-working-with-controllers.html) |
| Controller extension | `.js` or `.ds`, in the cartridge's `controllers` folder | [Controllers](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-working-with-controllers.html) |
| `require()` placement | Most limited scope; global requires load every request | [SFRA Modules](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-sfra-modules.html) |

## Check yourself

- When is `route:Redirect` emitted?
- Why would a team unsubscribe from `route:Complete`?
- Where does SFRA place parsed query string parameters?
- When does a request to an existing controller still fail with an error?

## Sources

- [SFRA Features and Components](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-sfra-features-and-comps.html)
- [Customize SFRA](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-customizing-sfra.html)
- [Controllers](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-working-with-controllers.html)
- [SFRA Modules](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-sfra-modules.html)
- [Explore Reference Architecture Cartridges and Structure](https://trailhead.salesforce.com/content/learn/modules/b2c-cartridges/b2c-cartridges-ref-architecture)
- [Third-Party Applications](https://developer.salesforce.com/docs/commerce/b2c-commerce/guide/b2c-third-party.html)
- [SFRA Server-side JavaScript: Server](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/sfrajsdoc/js/server/Server.html)
- [SFRA Server-side JavaScript: Global](https://salesforcecommercecloud.github.io/b2c-dev-doc/docs/current/sfrajsdoc/js/server/global.html)

## About the full unit

The "Core concepts", "Exam traps" and "Worked scenario" sections of this unit, its 15 linked practice questions, and unlimited timed mock exams are included with the B2C Commerce Developer pack (USD $19): https://www.certifyforce.com/practice-exams
