Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] API SDK extraction #548

Open
alpharder opened this issue Feb 4, 2024 · 0 comments
Open

[Feature request] API SDK extraction #548

alpharder opened this issue Feb 4, 2024 · 0 comments

Comments

@alpharder
Copy link
Contributor

alpharder commented Feb 4, 2024

Problem

We all love type-safe interaction between system components.

It's also a great idea to be able to use the same TypeScript types both in our server and client codebases, which is often referred as isomorphic TypeScript.

However, in a current state of Deepkit, we are limited to a cohesive approach, where both server and client codebases should be coupled: https://deepkit.io/documentation/rpc

This approach is also being used by some other popular tools like https://trpc.io/.

However, the state of a modern JS ecosystem is complicated – we have numerous runtimes (Node, Bun, Deno, Browser, React Native), a bunch of bundlers a build tools.

And sometimes making client and server codebases aware of each other becomes painful – you have to make sure the different tools all understand each other's output, TSConfigs and TS versions are compatible and etc.

Sometimes it's just hard to make these parts play well together.

Solution

Sometimes you just need to have your codebases isolated with some of the reused code being shipped as common packages.

There's an alternative approach for that – generating SDK code for clients to be used. Usually it has a form of an NPM package.

It has a downside of the necessity to be regenerated every time server APIs are changed, but this, however, gives additional flexibility and isolation.

Adepts of type-safety been using this approach for a long time, for example we took OpenAPI definitions and generated client SDKs based on that. It was great when there was no other solution, but it has lots of downsides, at least because OpenAPI definitions may be inaccurate or miss some of the important metadata. It's also completely unusable for RPC.

Suggestion

Provide an ability to generate code (package?), which:

  • is aware of specified HTTP and RPC public APIs, its details and re-exports I/O types as Typescript types which can be consumed in a client app;
  • doesn't depend on a server codebase at runtime;
  • can be used to call HTTP and RPC controllers at a given network address;
  • fully type-safe and provides validation, serialization and type casting abilities;

Usage example

Just an example, I haven't spent any time on thinking of a great DX.

Generate package

  1. Write a config file:
{
 exportTo: '../packages/server-sdk',
 controllersToExport: [ControllerA, ControllerB],
exportedPackageName: '@acme/server-sdk'
}
  1. Run code generation
npm run generate-sdk
  1. ../packages/server-sdk is now a regular NPM package;

  2. In a client codebase which depends on generated @acme/server-sdk package:

import { HttpApiClient } from '@acme/server-sdk';
import { SomeType} from '@acme/server-sdk'; // this type was used in a controller I/O definition and is available for client

const client = new HttpApiClient('example.com/api');

const result = await client.ControllerA.controllerMethod(type, safe, arguments);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant