The idea of doing a huge identifier switch like this in Ruby fills me with fear. Without the huge effort of getting to 100% test coverage, it would cause so many bugs in obscure corners of the system. OTOH, the function I wrote to define checked server routes is 34 lines long.
-
-
Prikaži ovu nit
-
(You can substitute JavaScript or any other dynamic language in place of Ruby in this tweet if you like; there's no difference in this case.)
Prikaži ovu nit -
I was worried that I was missing something huge and obvious – "why aren't people doing this?!" But I wasn't missing anything. If you're using TypeScript without static checking of API communication on both sides of the app then you're wasting much of its value.
Prikaži ovu nit -
Statically typed API communication is what made me finally do this port. The client was already in TypeScript; the server worked fine in Ruby. But keeping the two sides of the API in sync took so much effort. I had to write a lot of my own tools, but now I'm here and it's good.
Prikaži ovu nit -
Yes, I'm sharing type definitions between the backend and frontend. The server also does runtime validation of incoming API data. That validation and the static types come from a single type definition. And I have static checking that those runtime checks match the static types.
Prikaži ovu nit -
(How it works: the definition of the API is done via io-ts. Static types are extracted from io-ts validators with the usual `t.TypeOf<typeof validator>`. When you define a route, you mention the validator. The static API types are inferred for free from that validator.)
Prikaži ovu nit -
This adds minimal API definition overhead. Here's the smallest handler: post("/api/feedback.json", http://requests.feedback , requireUser( async ({user, input}) => { await mailer.sendFeedbackEmail(http://user.email , input.userComments) return {} } ) )
Prikaži ovu nit -
http://requests.feedback is the io-ts validator. requireUser pulls the user out of the session and redirects if they're not logged in. It wraps the handler because it adds the user key to that `{user, input}` object that you see the handler taking. Zero types named explicitly.
Prikaži ovu nit -
All of this has zero cost in terms of runtime speed or bundle size. The client-side bundle is 121 bytes smaller than when I started (because many of those identifier renames that I did were switching underscore_case to camelCase). All of the types are erased at runtime.
Prikaži ovu nit
Kraj razgovora
Novi razgovor -
-
-
Very cool, is this stuff on GitHub? Or is it proprietary code?
-
Take a look at this code from a couple years ago. The dependencies are mostly up to date and the client side is smallhttps://github.com/styfle/react-server-example-tsx …
- Još 3 druga odgovora
Novi razgovor -
Čini se da učitavanje traje već neko vrijeme.
Twitter je možda preopterećen ili ima kratkotrajnih poteškoća u radu. Pokušajte ponovno ili potražite dodatne informacije u odjeljku Status Twittera.