An API facade is an interface that presents an explicit consumer contract over operations implemented by another system. It controls how consumers request existing behavior; it does not remove the application’s underlying dependencies or create capabilities the backend lacks.

An anti-corruption layer has a related but distinct role: it translates between different subsystem models. Routing selects an implementation. Translation reconciles identifiers, values, errors, and concepts. A design can perform both functions, but each carries separate correctness obligations.

Start with a business operation

A useful boundary names a coherent operation rather than exposing an arbitrary sequence of storage actions. The operation needs inputs, authorization, validation, transaction behavior, and observable outcomes.

Suppose a client wants to approve an order. Writing an approved flag directly into a table is not equivalent to the original application operation if that operation also checks authority, validates the order state, records a decision, and initiates downstream work.

The facade must either invoke the complete required behavior or implement an explicitly accepted replacement for the omitted parts. A callable procedure is a candidate boundary, not proof that the business operation is complete.

Translate meaning at the boundary

Legacy and consumer models can disagree about identifiers, missing values, statuses, and error categories. A translation layer makes those differences explicit instead of requiring every consumer to understand the backend’s conventions.

If one subsystem uses a blank field for an unknown value and another interprets it as zero, passing the field unchanged preserves syntax while changing meaning. The boundary needs a defined mapping and behavior for values that cannot be translated.

New business rules also need an owner. Scattering them across the facade, client, and retained core makes it difficult to determine which implementation is authoritative. Translation explains model differences; it should not silently become an unrecorded second implementation of the same business policy.

Completion and failure remain business questions

A successful HTTP exchange establishes a result according to the interface contract. It does not automatically establish that a backend transaction committed or that downstream work completed. Those states must be represented deliberately.

A timeout creates a specific ambiguity when the backend can commit before the response reaches the caller. Retrying the request then requires knowledge of whether repeating the operation is safe or a mechanism for identifying the existing result.

The facade therefore needs explicit behavior for backend rejection, unavailable services, delayed completion, and repeated submission. Mapping every failure to a generic server error removes information consumers need to recover correctly.

The facade becomes an operating component

Routing and translation consume resources and introduce another failure boundary. A shared gateway can become a bottleneck or single point of failure. Its capacity and recovery need assessment alongside the retained application.

Observation must connect the incoming request to the backend result without exposing sensitive information. Otherwise, an operator sees an interface failure but cannot determine whether the original operation ran or where the response was lost.

Maintenance also continues behind the boundary. Runtime support, database operation, backups, and recovery remain obligations of the retained core. The facade changes how callers reach those obligations rather than transferring them out of existence.

Encapsulation and replacement

Encapsulation can be an endpoint when the existing implementation remains useful. It can also establish a boundary for later incremental replacement. These intentions require different measures of progress.

A facade-first change establishes consumer contracts while still routing to existing behavior. Actual replacement occurs when another implementation assumes a defined responsibility and the old dependency can be removed.

The scope rule is that interface stability applies to the declared consumer contract. It does not imply unlimited backend capacity, universal retry safety, or independence from the original runtime. The value of the boundary depends on making those continuing constraints explicit while giving consumers a coherent operation to use.