Skip to content

ctx altered in route middleware is retained on subsequent calls #16971

@Eli-Nathan

Description

@Eli-Nathan

Bug report

Required System information

  • Node.js version: 18
  • Strapi version: 4.9.2
  • Database: MySQL
  • Is your project Javascript or Typescript: JS

Describe the bug

A few months back I tried enriching an endpoints default populate behaviour using a route middleware and mentioned it in this comment on a Strapi forum thread.

I've since found an issue in which this request context is shared between subsequent api calls.

For example. If i wanted every request for books to return the author relation without having to worry about providing it in the query string:
Books Router config: /api/book/routes/book.js

module.exports = {
  routes: [
    {
      method: "GET",
      path: "/books",
      handler: "book.find",
      middlewares: ["populate-books"]
    },
    // ... more routes (with the same middleware if you want)
  ]
}

And then in /api/book/middlewares/populate-books.js:

const populateList = ["author"];

const enrichCtx = (ctx) => {
  if (!ctx.query) {
    ctx.query = {};
  }
  const currentPopulateList = ctx.query.populate || [];
  ctx.query.populate = [...currentPopulateList, ...populateList];
  return ctx;
};

module.exports = (config, { strapi }) => {
  return async (context, next) => {
    const newCtx = enrichCtx(context);
    context = newCtx;
    await next();
  };
};

This isn't too harmful for populate enrichment but when i try to set pageSize:

const enrichCtx = (ctx) => {
  if (!ctx.query.pagination) {
    ctx.query.pagination = {};
  }
  ctx.query.pagination = {
    ...ctx.query.pagination,
    pageSize: ctx.query.pagination?.pageSize || 100,
  };
  return ctx;
};

And then subsequently request a different endpoint like authors and provide pagination.limit in the request query, I get a 400 error because the request ends up with both limit and pagesize which isn't allowed.

Is it expected behavior to have the ctx retained between API calls?

Steps to reproduce the behavior

  1. Add a middleware that enriches the ctx for a single endpoint
  2. Add middleware to middlewares.js config file
  3. Make a request to this endpoint
  4. Make a request to another endpoint and log the ctx in the controller
  5. Observe combined ctx for both requests

Expected behavior

Applying a middleware to a route only applies to that route

Screenshots

If applicable, add screenshots to help explain your problem.

Code snippets

If applicable, add code samples to help explain your problem.

Additional context

Issue briefly described here

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions