Curated summary
Easy-to-use Toss Front SDK
API DesignSoftware ArchitectureInterface DesignFrontendDeveloper ExperienceAws CdkSdk DesignFacade Pattern
The post argues that an SDK’s stability depends not only on its internal implementation but also on how safely users can interact with it. Low-level APIs may expose every operation clearly, yet still allow human errors such as missing event handlers or cleanup. The recommended solution is an intent-driven Facade interface that simplifies common workflows, prevents misuse, and still provides low-level escape hatches for advanced cases.
Designing an SDK That Is Easy to Use
- Toss Place develops an external SDK for Toss Front payment terminals.
- The SDK allows third-party developers to build plugin apps that integrate with Toss services and run on the terminal.
- A simple-looking server API might require users to:
- Open a server.
- Register connection, message, and error handlers.
- Remove handlers.
- Close the server.
- This approach exposes implicit responsibilities to SDK users:
- A message callback might never be registered after a connection.
- Handlers might not be removed before shutdown.
- Improper cleanup can cause memory leaks and operational issues.
- Therefore, third-party implementation mistakes can directly affect platform reliability.
- A safer interface hides unnecessary internal steps:
const server = await sdk.start({ onConnection, onMessage });
await server.stop();
Facade as an Intent-Driven Interface
- The Facade pattern is commonly described as wrapping a complex subsystem with a simpler interface.
- In SDK design, its deeper purpose is to reorganize complexity around user intent rather than merely hide functionality.
- Users should express goals such as:
- “Start a server”
- “Upload a file”
- “Request a payment”
- Internal concerns—including authentication, retries, state management, listener registration, and cleanup—should be handled by the SDK.
- AWS CDK illustrates this distinction:
- L1 constructs closely represent raw CloudFormation resources and provide fine-grained control.
- L2 constructs provide intent-based APIs, such as creating a versioned S3 bucket with
versioned: true, while handling the underlying configuration automatically.
- The goal of a Facade is to reduce cognitive load and coupling, not simply to conceal every lower-level capability.
Combining High-Level and Low-Level APIs
- A well-designed SDK should provide both abstraction levels:
- High-level Facade: Handles the roughly 80% of common use cases through complete workflows.
- Low-level APIs: Serve as escape hatches for the roughly 20% of specialized cases requiring precise control.
- In the example:
- The Facade’s
start()method opens the server, registers listeners, coordinates connections, and returns a unified server handle. - Low-level APIs separately expose operations such as
open,close,send,disconnect, and event listeners.
- The Facade’s
- This layered design improves immediate developer experience while preserving long-term compatibility and extensibility.
Trade-offs and Escape Hatches
- Higher-level abstractions inevitably reduce some flexibility.
- Specialized requirements—such as keeping one connection while closing others—may not fit the Facade workflow.
- As orchestration becomes more sophisticated, the SDK maintainers inherit additional implementation and maintenance costs.
- Low-level escape hatches are therefore essential: users should be able to bypass the Facade when they need detailed control.
Practical Recommendation
Design SDK APIs around user intent and automate error-prone lifecycle management wherever possible. Offer a concise Facade for common workflows, but retain well-defined low-level interfaces so advanced users are not blocked by the abstraction.
Related reading
Continue with another curated summary.