Proposal for a new, more efficient typescript fetch code generation
See original GitHub issueI’ve noticed that for larger API surface areas the code generated can grow exponentially. One way around this would be to use TypeScript more effectively to enforce standard fetch conventions.
This can be accomplished by generating primarily types, which have 0 bytes of output along with some helper code; this means that essentially no matter how large your API is, the generated code is always a consistent size of a few kilobytes.
/** Routes */
type AddUserRoute = "/api/users";
type DeleteUserRoute = "/api/users";
type AddPostRoute = "/api/posts";
/** Models */
type AddPostModel = {
subject?: string
body: string
}
type AddPostReturnModel = {
id: number
}
type AddUserModel = {
name: string
age: number
}
type AddUserReturnModel = {
id: number
}
type DeleteUserModel = {
id: number
};
type TypedRequestInit<T = any> = T | ({ model: any } & RequestInit);
type TypedResponse<T = any> = T;
/** Constants */
const defaultRequestInfo : RequestInit = {
headers: {
"Content-Type": "application/json"
}
}
/** Overloads */
/** Generated Add Post description goes here */
async function fetchPost(info: AddPostRoute, init: TypedRequestInit<AddPostModel>): Promise<AddPostReturnModel>;
/** Generated Add User description goes here */
async function fetchPost(info: AddUserRoute, init: TypedRequestInit<AddUserModel>): Promise<AddUserReturnModel>;
async function fetchPost(info: RequestInfo, init: TypedRequestInit) {
const response = await fetch(
info,
"model" in init
? { method: "POST", ...defaultRequestInfo, ...init, body: JSON.stringify(init.model) }
: { method: "POST", ...defaultRequestInfo, body: JSON.stringify(init) }
);
return await response.json();
}
/** Overloads */
async function fetchDelete(info: DeleteUserRoute, init: TypedRequestInit<DeleteUserModel>): Promise<Response>;
async function fetchDelete(info: string, init: TypedRequestInit) {
let modelInInit = "model" in init;
let model = modelInInit ? init.model : init;
let keys = Object.keys(init)
let qs = "?";
for (let i = 0; i < keys.length; ++i) {
let key = keys[i];
let value = model[key];
if (i > 0)
qs += "&";
qs += encodeURIComponent(key) + "=" + encodeURIComponent(value);
}
return await fetch(
info + qs,
modelInInit
? { method: "DELETE", ...defaultRequestInfo, ...init }
: { method: "DELETE", ...defaultRequestInfo }
);
}
/** Example Usage */
fetchPost("/api/users", { name: "Ted", age: 25 });
fetchPost("/api/posts", { body: "This is a test" });
fetchDelete("/api/users", { id: 5 });
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:14 (1 by maintainers)
Top Results From Across the Web
Improve TS file size
[Review] Reduce file size of the Angular typescript client #1469 opened by ... Proposal for a new, more efficient typescript fetch code generation...
Read more >[Proposal] Untagged Variants for ReScript
The proposal includes a detailed design of the new type constructors, type inference, pattern matching, and handling of unknown values. We will ...
Read more >A Proposal For Type Syntax in JavaScript - TypeScript
The idea of this proposal is that JavaScript could carve out a set of syntax for types that engines would entirely ignore, but...
Read more >Introducing Codegen for Hydrogen: Automated Types ...
In this article, we'll explore how to manually incorporate types with the Storefront API, look at a pre-generated approach and then dive ...
Read more >Node.js and TypeScript Tutorial: Build a CRUD API
Learn how to use TypeScript to build a feature-complete Express API. Learn how to use TypeScript with Express to create, read, update, ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Hey @RicoSuter and all - I just published my templates and some tests to the following repo:
https://github.com/wivuu/nswag-liquid-slim
The templates can be found here: https://github.com/wivuu/nswag-liquid-slim/tree/master/Templates
I’ve been using the templates in my app and so far they’re easy to use and pretty reliable! I’m making the license MIT so please feel free to incorporate them however you want; or if you don’t want to please let me know and I will probably create my own supplemental nuget package.
If anyone has any suggestions/improvements to reduce output or improve performance please feel free to submit PRs.
Update:
I just converted my own application for a real-world usecase, here’s a before and after comparison
Most of the changes were very straighforward, for example: