-
-
Notifications
You must be signed in to change notification settings - Fork 532
run-time serialization and deserialization of custom formats #1328
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
Comments
Not necessarily; I think middleware support (#1122) is still on the table. I just didn’t want to jump into adding that in a way that breaks type safety (it’s hard, for the same reasons your proposal is hard, which I’ll come back to). I’m not opposed to “opt-in slowness” where it’s fast by default, but you can slow it down and opt into runtime transformation if you want to.
I might be wrong, but it looks like One possible way to solve this would be codegen, maybe via a Vite plugin or something. I’m thinking about how SvelteKit and some GraphQL tools compile types/minimum code automatically in the background as you work. For this, there could be some component of scanning the fetch calls you’re writing (which are statically-analyzable, otherwise the TypeScript inference wouldn’t be working), comparing it against the original schema, and then using that to provide the minimum data that the serializers/deserializers need to do the transforms. Ideally, this would also plug into Any codegen utils would probably be a separate package from openapi-fetch, and it’d definitely be experimental for a while as the first attempt would probably be flat-out wrong, and it’d take some iteration to get right. I know that’s sort of a wild/complex idea, and I glossed over a lot of detail. But all that said, it seems possible? I can’t think of a pure runtime way to accomplish this off the top of my head but will give it some thought. |
Yes, I believe it does. It doesn't generate type-safe responses, so I use the two tools to complement one-another; one for types, and one for behavior.
I agree an ahead-of-time compilation process makes a lot of sense. The |
I currently use import { Fetcher } from 'openapi-typescript-fetch';
export const fetcher = Fetcher.for<paths>();
import { paths } from 'src/generated/admin';
export const availabilityGet = fetcher.path("/availability/{availabilityId}").method("get").create();
export const availabilitiesPost = fetcher.path("/availabilities").method("post").create();
… When I build the client, it imports from there, and any endpoints not used by the client get tree-shaken away. 🌳 🪓
|
@duncanbeevers that sounds great, how are you generating the file? Would you mind sharing? :-D |
@snarky-puppy It's just a simple traversal+transformation of the schema json. Start with |
Going to start exploring this this week. Ideally it involves a third-party library that’s better at this than handrolling something (and is swappable if people don’t like it). I have a feeling like this will slot into middleware (#1122), but will still need either an example, or maybe even official middleware to guarantee it works well. |
This would be an amazing feature! We could use this for our date fields for example. These are defined as Best thing would be the ability to define custom type transform (string to custom Date type in this case) in combination with |
The API of my project makes heavy use of types from the Temporal API. Automatic deserialization would make this (already great) library even more useful. |
This issue is stale because it has been open for 90 days with no activity. If there is no activity in the next 7 days, the issue will be closed. |
This is AFAIK still an issue. |
You've talked about using middlewares to serialize/deserialize dates, but how do I know which fields to serialize/deserialize without access to either the openapi schema or the typescript ast? |
You are correct that some form of structure must be shipped to the client, but this can be significantly less than the entire schema; only the "special" parts of the response that don't parse natively out of I'll try and write this up in a more-shareable way, but here's what I've done to generate minimal deserializers. To begin, consider the problem; we have a parsed JSON object, and we would like to selectively rewrite parts of it, taking the primitive value (typically a string) and replacing it with something else.
In order to identify the minimal deserializer's shape we can build it up from the schema. My algorithm uses recursive descent, but there are probably smarter ways to implement it.
In my implementation I build the dependency graph first and then run some deduplication passes on the resulting structure, rather than generating code during the traversal, but that's the general idea. |
🗣️ Description
I want automatic deserialization + serialization of custom formats; particularly,
Date
values.Currently, I get nice type signatures for requests, and for response bodies; however those types are limited to values which can be serialized to JSON. This precludes sending Dates directly to the wire, and reading Dates from responses.
Instead, in my client-side code I often have to create bespoke deserializers which must be used after fetching.
🎨 Ideal Solution
openapi-express-validator
has aserDes
option with a great API for transforming custom values.openapi-typescript
(using transform) generatesserDes
-compatible types (eg;createdAt: Date
instead ofstring
)openapi-fetch
has abodySerializer
option, but this operates far too late to make these transformations.👑 Proposal
serDes
option toopenapi-fetch#createClient
I recognize this is something of a departure from the core philosophy of this package; it's nice to have such a thin run-time, and not have to traverse+transform any data structures.
However, I appreciate the strictness and opinions of
openapi-typescript
, and want to leverage more of that interpretation throughout the stack.Perhaps this could be implemented as a pluggable visitor, rather than integrated into the core
openapi-fetch
library.I've been mulling this for a little while, and figured I'd at least solicit some feedback about the idea.
Checklist
The text was updated successfully, but these errors were encountered: