ContentsThe library

Designing an Interface to Call

Every Awkward Interface You Have Ever Used Was Awkward for the Same Reason, and the Reason Was Decided in the First Half Hour

The nouns an interface exposes are chosen once and lived with forever. Here is how to find the real ones, how to tell when you have the wrong ones, and what wrong ones cost.

Things, not actions

An interface can be organised two ways. Either it is a list of actions, one

entry for each thing somebody wants done, or it is a list of things, each with

a short fixed set of operations.

The difference does not look important on the first day and determines

everything afterwards.

FIG 1The same capability, organised twice
plaintext
organised as actions

  createOrder
  cancelOrder
  addItemToOrder
  removeItemFromOrder
  applyDiscountToOrder
  getOrderForCustomer
  getOrdersForCustomerLastMonth
  markOrderShipped
  resendOrderConfirmation

organised as things

  orders              create, read, update, cancel
  orders/items        add, remove, list
  orders/shipments    create, read
  orders/confirmations  create
Nine entries against four, and the real difference is what happens next. The first list grows by one every time anybody wants anything, and each new entry has its own shape, its own parameters and its own failure modes. The second list grows only when a genuinely new thing appears, and every operation on a known thing already has an obvious shape.

Read the two lists again and notice where the information is. In the first

list, the thing being acted on is buried inside a verb, so the reader has to

know that an order has items by noticing that one of the entries mentions

them. In the second, the structure of the domain is visible in the structure of

the interface, which is what makes an interface learnable rather than something

you look up each time.

Finding the real ones

So the exercise is to find the things. Two sources are tempting and wrong.

Your database tables are wrong because they encode decisions about storage

efficiency that nobody outside should be made to care about. If the orders

table was split in two for performance, that is not two things, it is one thing

stored in an inconvenient way. The reverse is also common: three domain things

sharing one table because they have similar columns.

Your internal class names are wrong for a related reason. They have usually

accumulated qualifiers that refer to your own history, and a caller should not

have to learn your history in order to place an order.

The right source is how the caller already talks.

FIG 2Turning a sentence into an interface
Three questions, applied to every candidate noun. The second decides where it sits, the third decides whether it is a thing at all, and most arguments about interface design are really disagreements about one of those two answers.

A caution about the obvious nouns. The ones everybody agrees on, customers and

orders and invoices, are rarely where the trouble is. The trouble is in the

things nobody named, which turn up as verbs that will not fit anywhere, and

that is the third section.

Identity and addresses

Once a thing has a name, a caller needs a way to refer to a particular one of

them, and that way is a promise.

FIG 3Candidate identifiers, judged
can changereadable by a personsafe to put in an addressafe to store in another
the display name1100
a number from the storag0111
an identifier generated 0011
position in a list1100
an email address0110
the current status1000
Read the first column against the third. Everything that can change is unsafe, and the reason is that an address is a promise that it keeps meaning the same thing. A name in an address converts a rename into a broken reference, for every caller who stored it, including the ones you do not know about.

The storage number deserves a note, because it is the usual default and it has

one specific problem. It exposes how many of something you have and the order

in which they were created, which is information most businesses would not

publish deliberately. It also makes it guessable what other identifiers exist,

which turns an authorisation mistake into a bulk extraction.

The generated identifier avoids both and costs almost nothing. It is not

readable by a person, which is a genuine loss during debugging, and the usual

answer is a short prefix naming the kind of thing, so that a reader seeing one

in a log knows immediately what it refers to.

Recognising a wrong one

Three signals, in increasing order of seriousness.

FIG 4One awkward operation, traced to its cause
stepsymptomthe workaroundwhat it really meansthe fixwhat happened
1a verb fits nothingan action entry bolted on the sidea thing is missingname the thing the verb createsThe commonest. Approve, cancel, publish, refund. Each of those produces something that could be named: an approval, a cancellation, a refund, and once named it has an identifier, a time, an author and a reason, all of which the verb had nowhere to put.
2one thing has five shapesa parameter selecting the shapetwo things share a namesplit themIf the response differs structurally depending on who asks or why, the single name is covering several distinct things that happen to share storage.
3three calls to answer one questiona combined entry for that casethe nesting is wrongmove the thing under what it belongs toIf every caller fetches an order and then its items and then its shipments, the shape does not match how the thing is used, and the special combined entry is a symptom rather than a solution.
3 steps
Each row is the same mistake in a different disguise, and in each case the workaround is cheap and permanent while the fix is cheap only today. That asymmetry is why these accumulate: nobody is ever wrong to add the workaround, and nobody is ever free to remove it later.

The first signal is worth dwelling on, because it is the most useful tool in

this lesson. When somebody says the interface needs an approve operation and

there is nowhere to put it, the right response is to ask what approving

produces. The answer is an approval: it happened at a time, somebody did it,

it may have a note attached, it can be looked up afterwards, and occasionally

it can be withdrawn. All of that is a thing, and the verb was a thing in

disguise.

This reframing does more than tidy the interface. The list of approvals is

immediately useful, the time and the author have somewhere to live rather than

being columns bolted onto the order, and withdrawing an approval becomes an

ordinary operation on an ordinary thing rather than a second verb.

FIG 5When the nouns can still be changed
free to changea conversationa migration project20040060080010000design1first caller40an internal team or two1200publiccallers depending on the interface
The window is extremely short and it closes without anybody noticing. The cost of renaming a thing is roughly proportional to how many callers have written its name into their own code, and at the right-hand end of this scale the usual outcome is that the wrong name stays forever and gets a comment explaining it.

So the half hour at the start is worth more than any week of work afterwards.

Write the sentences down, take the nouns, ask the two questions about each, and

look specifically for the verbs that fit nowhere, because that is where the

missing things are hiding.

With the things named, the next question is what may be done to each of them,

and the useful classification is not what the operations are called but what

happens when one of them runs twice.

Recap

  • An interface exposes things, and the operations follow from them, so a wrong thing makes every operation afterwards awkward in a way no amount of care can fix.
  • The real things are the ones a caller already talks about, not the ones your storage happens to hold, and the two are different more often than people expect.
  • A verb that will not fit any noun is evidence that a noun is missing, and the missing noun is nearly always the thing the verb was going to create.

This is the reading half

Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.

The contents

NextChoosing the Operations →

The rest of this course

  1. 01Every Awkward Interface You Have Ever Used Was Awkward for the Same Reason, and the Reason Was Decided in the First Half Houryou are here
  2. 02There Are Only Two Questions Worth Asking About Any Operation, and Neither of Them Is What It Is Calledopening only
  3. 03Your Error Message Is Read by a Program First and a Human Second, and Almost Every Interface Gets That Order Backwardsopening only
  4. 04The Second Call Is Not a Mistakeopening only
  5. 05Counting From the Start Versus Remembering the Placeopening only
  6. 06A Limit Is Only Useful If Somebody Can Obey Itopening only
  7. 07Hand Back a Receipt, Not an Answeropening only
  8. 08Add, Migrate, Then Removeopening only

Read alongside