In Patterns of Enterprise Application Architecture, Martin Fowler introduced the idea of a Gateway: a class that encapsulates access to an external resource (like a database table or remote service). It was a powerful idea to make dependencies explicit and isolate them behind clear boundaries.
In my opinion, “Gateway” has felt a bit vague, I favour names that better explain intent and layering.
| Convention | Explanation | Example |
|---|---|---|
| Client | Use when the class calls an outside API or third-party system. | EmailClient calls an email delivery service. |
| Repository | Use when the class saves to or reads from a database. This is equivalent to Table Date Gateway. | UserRepository loads and saves user entities. |
| Entity | Similar to Repository, use when the class saves to or reads from a database. This is equivalent to Row Data Gateway | User loads and save an user instance in the database. |
| Service | Use when the class does business logic or orchestration beyond simple calls or storage. | InvoiceService applies rules and coordinate repositories. |
| Provider | Use when the class offers a capability through different interchangeable. A Provider may internally use one or more Repositories or Clients, but exposes a single, consistent interface to the Service layer. | AuthProvider might use LDAP (via LdapClient), OAuth (via OAuthClient), or DB lookups (via UserRepository), but the AuthService only depends on the AuthProvider interface |
| Adapter | Use when the class translates or bridges between two models or protocols. | PaymentAdapter converts our domain object to an external API request. |
Layering (not either/or):
- Controller/UI → Service → Provider
- Provider can wrap Repositories and/Clients
- Adapter fits in wherever translation is required
Example Flow

Who wraps who?
Client is the lowest-level piece - it talks directly to external API (e.g making HTTP calls)
Adapter sits in front of client, translating between your domain model and the client’s request/response formats.
Provider can wrap either a client (or multiple clients/repositories) to expose one clean capability.
Service orchestrates business logic and uses the provider.