REQUIREMENTS & MODELING / OBJECT DESIGN BRIEF

API and interface design

API and interface design is choosing the public methods, parameters, return types, and error behavior that other code will depend on.

IntermediatePhase 03 / Topic 8 of 8ResponsibilitiesCollaborationsExtensibility
01

Overview

API and interface design is choosing the public methods, parameters, return types, and error behavior that other code will depend on. A good API is easy to use correctly and hard to use incorrectly: it uses domain vocabulary, small focused methods, clear types instead of primitives, predictable errors, and stable contracts.

In LLD interviews, the public API of your main classes is often what the interviewer evaluates first: park(vehicle) returning a Ticket, not assign(int floor, int row, int col, String plate, int type). Designing the API before internals keeps the solution centered on use cases.

A coffee machine's buttons

Good machines offer 'Espresso', 'Latte', 'Hot water'. Bad ones ask you to set water temperature, pressure, and grind size separately for every cup. Both work, but only one is hard to misuse.

02

When to use it

  • Defining the entry points of any class or module.
  • Library and SDK design.
  • The first coding step in an LLD interview.
03

Where it shows up in interviews

Entry-point design

Recognize it when: 'what methods would your class expose?'

  • Design a parking lot API
  • Design a rate limiter interface
  • Design a cache interface
Library design

Recognize it when: reusable component for other teams.

  • Design a logging framework
  • Design a task scheduler
04

Where it is used in real software

Java Collections and java.time

java.time replaced error-prone Date/Calendar APIs with immutable, well-named types.

Stripe API

Praised for consistent naming, idempotency keys, and expandable objects.

Joshua Bloch's API guidelines

'APIs should be easy to use and hard to misuse' is a widely cited principle.

05

Key terms

Contract
Inputs, outputs, errors, and side effects callers can rely on.
Primitive obsession
Using raw strings and ints for domain concepts.
Command-query separation
Methods either change state or return data, not both.
Backward compatibility
Changes that do not break existing callers.
Fail fast
Reject invalid input immediately with a clear error.
06

How it works, step by step

  1. 1
    Start from use cases

    Each use case needs an entry point.

  2. 2
    Name with domain verbs

    park, exit, reserve, cancel.

  3. 3
    Use rich types

    Vehicle, Money, TicketId instead of strings and ints.

  4. 4
    Define errors

    Domain exceptions or result types for expected failures.

  5. 5
    Minimize surface

    Expose only what callers need; keep the rest private.

07

Weak vs strong API

Parking lot entry

Step 1 / 4
AspectWeakStrong
Signatureassign(int, int, String, int)park(vehicle: Vehicle): Ticket
Meaning of argumentsWhich int is floor?Types document themselves
FailureReturns -1Throws LotFullException / returns Result
Future change (add EV spots)New int flagVehicle subtype or spot feature

NOWAspect: Signature | Weak: assign(int, int, String, int) | Strong: park(vehicle: Vehicle): Ticket

Strong types and domain names make incorrect calls hard to write.

08

Implementation

type TicketId = string & { readonly brand: "TicketId" };type Money = { cents: number; currency: "USD" }; type ParkResult =  | { ok: true; ticketId: TicketId; spot: string }  | { ok: false; reason: "LOT_FULL" | "VEHICLE_ALREADY_PARKED" }; export interface ParkingLot {  park(vehicle: Vehicle): ParkResult;               // command with an explicit outcome  exit(ticketId: TicketId, at: Date): Money;       // throws UnknownTicket for programmer errors  availability(): ReadonlyMap<VehicleSize, number>; // query, no side effects} // Callers must handle both outcomes; the compiler enforces itconst result = lot.park(new Car("KA-01"));if (!result.ok) console.log("Cannot park:", result.reason);
09

Complexity and performance

Public methods per classFew (3-7)

Small surface.

Breaking change costAll callers

Design carefully.

10

Trade-offs

Exceptions vs result types

Exceptions keep happy paths clean; result types force callers to handle expected failures.

Flexibility vs simplicity

Many optional parameters make APIs powerful but confusing; use builders or separate methods.

11

Variants and related techniques

Fluent APIs

Chainable methods for configuration and queries.

Remote APIs

REST and gRPC follow the same principles plus versioning and idempotency.

12

Common mistakes

  • Boolean flag parameters (book(seat, true)).

    Fix: Use separate methods or an enum.

  • Returning null for 'not found'.

    Fix: Return Optional or a result type.

  • Leaking internal types.

    Fix: Return domain types or read-only views.

13

Interview questions

What makes an API easy to use correctly?

Domain names, rich types instead of primitives, few parameters, predictable errors, no hidden side effects in queries, and sensible defaults.

Exceptions or return codes for 'lot full'?

It is an expected business outcome, so a result type or a specific domain exception both work; the key is that callers are forced or clearly guided to handle it, unlike magic values like -1.

14

Practice problems

ProblemDifficultyWhat it trains
Design the public API of an LRU cacheEasyContracts.
Design the API of a task scheduler libraryMediumBuilders and errors.