Skip to main content
interlace
Plugin: modularityRules

enforce-rest-conventions

Report route paths whose first segment is not a plural resource name.

Report a route registration whose static path names a singular resource (/user rather than /users).

This rule is part of eslint-plugin-modularity.

Quick Summary

AspectDetails
SeverityError (code quality)
Auto-Fix❌ No
CategoryModularity
Suggestions✅ Use a plural resource name

Rule Details

The rule reads route registrations: a call of get, post, put, patch, delete, head or options on any object (app.get(...), router['post'](...)). When the first argument is a static string that starts with /, the rule reports it if its first segment:

  • does not end in s, and
  • is longer than three characters, and
  • the path has no route parameter (:) anywhere.

It does not report a path with a parameter (/user/:id), the root (/), a plural path (/orders), or a path built at run time.

Heuristic. Whether a segment is a singular noun is read from its spelling, so non-resource endpoints such as /health, /login or /search are reported too, and a get call on a non-router object that takes a path-like string is read as a route. Turn checkResourceNaming off where that does not fit.

Configuration

OptionTypeDefaultDescription
checkResourceNamingbooleantrueReport singular resource paths. false turns the rule's only check off
checkStatusCodesbooleantrueReserved: no status-code check exists yet
checkHttpMethodsbooleantrueReserved: every method the rule reads is a valid REST method

Examples

❌ Incorrect

app.get('/order', listOrders);
router.post('/invoice', createInvoice);

✅ Correct

app.get('/orders', listOrders);
app.get('/orders/:id', getOrder);
router.post('/invoices', createInvoice);

Configuration Examples

// eslint.config.mjs
export default [
  {
    rules: {
      'modularity/enforce-rest-conventions': ['error', { checkResourceNaming: true }],
    },
  },
];

Use this rule

npm install -D oxlint-plugin-modularity
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-modularity"],  "rules": {    "modularity/enforce-rest-conventions": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-modularity'],    rules: {      'modularity/enforce-rest-conventions': 'error',    },  },});

oxlint-plugin-modularity re-exports eslint-plugin-modularity/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.