(no title)
shiny | 5 years ago
I have an endpoints.ts file, shared between client/server, which has something like:
export type Endpoints = {
createProduct: {
path: '/api/products.json';
method: 'POST';
clientSends: { name: string };
serverResponds: ProductJSON;
};
}
The client can do `makeRequest('createProduct', ...)` and the Express server can use `registerEndpoint('createProduct', ...)` which must adhere to the schema defined above.TypeScript's structural typing helps a lot here.
Of course, I can "lose" typing through things like raw SQL queries (working on a mini db helper library to help with that), but so I'll have to validate that the endpoints return what they say they do through tests (probs using io-ts).
I'm just getting started (coming from Rails). Not sure what the "correct" way to do this is, but my approach works so far. Would also be nice to have a generic way to create REST endpoints for a given resource, but meh.
[1]: https://www.executeprogram.com/blog/porting-to-typescript-so...
eyelidlessness|5 years ago
If you combine that with generics on whatever function defines your routes, you can validate API boundaries and business logic boundaries in the compiler. This applies to any boundary (I could link to Gary Bernhardt on that topic but I’m on phone), and you can do it as generically (like you said, io-ts) or specifically (take a look at zapatos for type safe SQL) as you like.
For HTTP boundaries, I’ll drop some pseudocode of how I’m doing this in my library:
shiny|5 years ago
Looks like I need to incorporate encoders/decoders into my scheme. I might just steal that code outright.
Thanks for the Zapatos rec, that looks perfect.
fyi, my current generic method sigs looks like:
Dropping all of these typing shenanigans and going back to Elixir/Phoenix is always half-tempting, but I will soldier on for now...