Skip to content
routebase
API Governance10 chapters

Chapter 04 of 10

Rules of Your Own

When a house convention earns an automated check, what a condition-based rule can express, and how to write one that does not fire on half your endpoints.

Every organisation has conventions no tool ships with. The question is which of them are worth turning into a check, because the answer is not all of them.

Three tests before you write one

A house convention earns an automated check when three things hold at once.

It has to recur. A convention that comes up twice a year is cheaper to catch in a review than to maintain as a rule, and the rule will be stale by the time it next fires.

Somebody has to be able to name the cost. If nobody can say what goes wrong when the convention is ignored, the rule is a preference and it will lose its first argument.

A machine has to be able to decide it. The convention needs a target, a field and a condition, as the previous chapter describes, and a convention that resists that split needs rewriting rather than automating.

What a condition can carry

Condition-based rules are deliberately small, and knowing the shape of the box is what stops you from fighting it.

A rule points at one target, which is an operation, a schema or the specification itself. It picks one field on that target, such as a path, a summary, an operation identifier or a contact address. It then applies one condition, which is typically that the field exists, contains something, equals something or matches a pattern.

That covers more than it sounds like. Internal header prefixes, operation identifier naming, mandatory summaries, a contact address that has to be a team alias rather than a person, and path patterns your platform requires are all one field and one condition.

What it cannot carry

The limits are worth knowing before you design a convention around them.

A condition looks at one field, so a rule that compares two fields against each other is out of reach. A condition does not count, so a rule about how many parameters an operation may have has nowhere to go. A condition sees one target, so a rule that checks an operation against a schema somewhere else in the document cannot be written this way.

When a convention needs one of those, you have two honest options. Restate it as something narrower that a condition can see, or accept that it belongs in a design review. Writing an approximation that fires on the wrong things is the option that costs you the most, because it damages the credibility of every other rule.

Writing one that does not cry wolf

Most bad custom rules are bad in the same three ways, and all three are avoidable in the first draft.

Pick the narrowest target. A rule on the specification fires once, and a rule on every operation fires everywhere. If the convention really concerns operations, keep it there rather than approximating it at the document level.

Anchor the pattern. An unanchored expression matches a substring, so a rule meant to require a team- prefix will happily accept customer-team-orders. Anchoring both ends turns a rule that quietly passes into one that means what it says.

Start it advisory. Run the rule at an informational severity for a week and read the output before deciding anything. A rule that fires on a third of your endpoints is usually describing a convention you believed you had rather than one you actually have.

The rule you should not write

There is one category worth naming, because it is tempting and it never works.

Rules that encode a judgement produce findings nobody can act on. A pattern that tries to detect a vague summary will flag good ones and miss bad ones, because the thing being judged is meaning rather than form. The same applies to any rule whose violation prompts an argument about intent rather than a fix.

Those conventions are real, and they belong in the review that the mechanical rules just freed up.

In Routebase

Custom rules are declarative rather than scripted, which is what keeps them readable by the next person.

The Create Custom Rule dialog with a name reading Every operation needs a summary, a description, a Category dropdown on Completeness, a Severity dropdown on Warning, a Target dropdown on Endpoint, a Field dropdown on Summary and a Condition dropdown on Exists.
A rule is a target, a field and a condition, with the category and severity it carries into the rules table alongside the built-in ones.

A rule targets an endpoint, a schema or the specification, and the available fields depend on which of the three you pick. Endpoints expose the path, summary, description, operation identifier and method, schemas expose the name and description, and the specification exposes its name, version, description, server URL, contact address and licence identifier.

The condition is regex, contains, equals or exists, and patterns are validated before the rule is saved. You choose the category and the severity yourself, so a custom rule sits in the same table as the built-in ones with a custom badge. It can be enabled, edited, disabled or deleted from the same page.

Anything outside a single field and a single condition is not expressible, which is the trade this design makes on purpose. The Style Guide guide lists the fields available on each target.

Frequently asked questions

When should you write a custom API lint rule?

When the convention recurs, somebody can name what goes wrong without it, and a machine can decide it from the document. All three have to hold. A convention that comes up once a year is cheaper to catch in review, and one nobody can justify will lose its first argument whether or not a tool enforces it.

What can a condition-based API rule check?

One field on one target, against one condition. That covers a great deal in practice, including path patterns, required summaries, operation identifier prefixes and specification metadata such as a contact address. It does not cover anything that needs two fields compared against each other, anything that counts, or anything that looks at a different part of the document.

How do you stop a lint rule from producing false positives?

Narrow it before you tighten it. Pick the most specific target the rule can sit on, and anchor the pattern at both ends so it cannot match a substring by accident. Start it at an advisory severity as well, so the first week of output is data rather than an obstacle. A rule that fires on a third of your endpoints is usually describing a convention you do not actually have.

Last reviewed by The Routebase Team.

Ready to ship on it?

Routebase is live. Design your API once — docs, mocks, tests, and monitoring all follow from the same source.

14-day Pro trial — no credit card required.