Skip to main content

Requests and Responses

🏗 Work in progress

The content of this page might not be fully up-to-date with Strapi 5 yet.

The Strapi back end server is based on Koa. When you send requests through the REST API, a context object (ctx) is passed to every element of the Strapi back end (e.g., policies, controllers, services).

ctx includes 3 main objects:

  • ctx.request for information about the request sent by the client making an API request,
  • ctx.state for information about the state of the request within the Strapi back end,
  • and ctx.response for information about the response that the server will return.
💡 Tip

The request's context can also be accessed from anywhere in the code with the strapi.requestContext function.

👀 Info

In addition to the concepts and parameters described in the following documentation, you might find additional information in the Koa request documentation, Koa Router documentation and Koa response documentation.

Simplified Strapi backend diagram with requests and responses highlighted
The diagram represents a simplified version of how a request travels through the Strapi back end, with requests and responses highlighted. The backend customization introduction page includes a complete, interactive diagram.

ctx.request

The ctx.request object contains the following parameters:

ParameterDescriptionType
ctx.request.bodyParsed version of the body.Object
ctx.request.filesFiles sent with the request.Array
ctx.request.headersHeaders sent with the request.Object
ctx.request.hostHost part of the URL, including the port.String
ctx.request.hostnameHost part of the URL, excluding the port.String
ctx.request.hrefComplete URL of the requested resource, including the protocol, domain, port (if specified), path, and query parameters.String
ctx.request.ipIP of the person sending the request.String
ctx.request.ipsWhen X-Forwarded-For is present and app.proxy is enabled, an array of IPs is returned, ordered from upstream to downstream.

For example if the value were "client, proxy1, proxy2", you would receive the ["client", "proxy1", "proxy2"] array.
Array
ctx.request.methodRequest method (e.g., GET, POST).String
ctx.request.originURL part before the first /.String
ctx.request.paramsParameters sent in the URL.

For example, if the internal URL is /restaurants/:id, whatever you replace :id in the real request becomes accessible through ctx.request.params.id.
Object
ctx.request.pathPath of the requested resource, excluding the query parameters.String
ctx.request.protocolProtocol being used (e.g., https or http).String
ctx.request.queryStrapi-specific query parameters.Object
ctx.request.subdomainsSubdomains included in the URL.

For example, if the domain is tobi.ferrets.example.com, the value is the following array: ["ferrets", "tobi"].
Array
ctx.request.urlPath and query parameters of the requested resource, excluding the protocol, domain, and port.String
Differences between protocol, origin, url, href, path, host, and hostname :

Given an API request sent to the https://example.com:1337/api/restaurants?id=123 URL, here is what different parameters of the ctx.request object return:

ParameterReturned value
ctx.request.hrefhttps://example.com:1337/api/restaurants?id=123
ctx.request.protocolhttps
ctx.request.hostlocalhost:1337
ctx.request.hostnamelocalhost
ctx.request.originhttps://example.com:1337
ctx.request.url/api/restaurants?id=123
ctx.request.path/api/restaurants

ctx.request.query

ctx.request provides a query object that gives access to Strapi query parameters. The following table lists available parameters with a short description and a link to the relevant REST API documentation section (see REST API parameters for more information):

ParameterDescriptionType
ctx.request.query
ctx.query
The whole query object.Object
ctx.request.query.sortParameters to sort the responseString or Array
ctx.request.query.filtersParameters to filter the responseObject
ctx.request.query.populateParameters to populate relations, components, or dynamic zonesString or Object
ctx.request.query.fieldsParameters to select only specific fields to return with the responseArray
ctx.request.query.paginationParameter to page through entriesObject
ctx.request.query.publicationStateParameter to select the Draft & Publish stateString
ctx.request.query.localeParameter to select one or multiple localesString or Array

ctx.state

The ctx.state object gives access to the state of the request within the Strapi back end, including specific values about the user, authentication, route:

ParameterDescriptionType
ctx.state.isAuthenticatedReturns whether the current user is authenticated in any way.Boolean

ctx.state.user

The ctx.state.user object gives access to information about the user performing the request and includes the following parameters:

ParameterDescriptionType
ctx.state.userUser's information. Only one relation is populated.Object
ctx.state.user.roleThe user's roleObject

ctx.state.auth

The ctx.state.auth object gives access to information related to the authentication and includes the following parameters:

ParameterDescriptionType
ctx.state.auth.strategyInformation about the currently used authentication strategy (Users & Permissions plugin or API tokens)Object
ctx.state.auth.strategy.nameName of the currently used strategyString
ctx.state.auth.credentialsThe user's credentialsString

ctx.state.route

The ctx.state.route object gives access to information related to the current route and includes the following parameters:

ParameterDescriptionType
ctx.state.route.methodMethod used to access the current route.String
ctx.state.route.pathPath of the current route.String
ctx.state.route.configConfiguration information about the current route.Object
ctx.state.route.handlerHandler (controller) of the current route.Object
ctx.state.route.infoAdditional information about the current route, such as the apiName and the API request type.Object
ctx.state.route.info.apiNameName of the used API.String
ctx.state.route.info.typeType of the used API.String

ctx.response

The ctx.response object gives access to information related to the response that the server will return and includes the following parameters:

ParameterDescriptionType
ctx.response.bodyBody of the response.Any
ctx.response.statusStatus code of the response.Integer
ctx.response.messageStatus message of the response.

By default, response.message is associated with response.status.
String
ctx.response.header
ctx.response.headers
Header(s) sent with the response.Object
ctx.response.lengthContent-Length header value as a number when present, or deduces it from ctx.body when possible; otherwise, returns undefined.Integer
ctx.response.redirect
ctx.response.redirect(url, [alt])
Performs a 302 redirect to the URL. The string "back" is special-cased to provide Referrer support; when Referrer is not present, alt or "/" is used.

Example: ctx.response.redirect('back', '/index.html');
Function
ctx.response.attachment

ctx.response.attachment([filename], [options])
Sets Content-Disposition header to "attachment" to signal the client to prompt for download. Optionally specify the filename of the download and some options.Function
ctx.response.typeContent-Type header, void of parameters such as "charset".String
ctx.response.lastModifiedLast-Modified header as a Date, if it exists.DateTime
ctx.response.etagSets the ETag of a response including the wrapped "s.
There is no corresponding response.etag getter.
String

Accessing the request context anywhere

Strapi exposes a way to access the current request context from anywhere in the code (e.g. lifecycle functions).

You can access the request as follows:

const ctx = strapi.requestContext.get();

You should only use this inside of functions that will be called in the context of an HTTP request.

// correct

const service = {
myFunction() {
const ctx = strapi.requestContext.get();
console.log(ctx.state.user);
},
};

// incorrect
const ctx = strapi.requestContext.get();

const service = {
myFunction() {
console.log(ctx.state.user);
},
};

Example:

./api/test/content-types/article/lifecycles.js

module.exports = {
beforeUpdate() {
const ctx = strapi.requestContext.get();

console.log('User info in service: ', ctx.state.user);
},
};
✏️ Note

Strapi uses a Node.js feature called AsyncLocalStorage to make the context available anywhere.