File Upload & Client implementation #2821
Replies: 3 comments
-
Thank you for appreciation and your feedback, @Alexandregirbal .
express-zod-api/express-zod-api/src/integration.ts Lines 39 to 43 in 7b92ff0
💡 nice idea. If it's static, then it could be an option for
Well, it's awesome that they do that for you.
Not sure what you mean. I don't have such issue with input transformations. Endpoint: express-zod-api/example/endpoints/retrieve-user.ts Lines 21 to 26 in 7b92ff0 Client types: express-zod-api/example/example.client.ts Lines 8 to 12 in 7b92ff0 Let me know more details about this case. |
Beta Was this translation helpful? Give feedback.
-
About the baseUrl / serverUrl
I understand it is possible to pass a serverUrl (let's call it this way).
In the end, I wrote my own About the uploadYou are right, express-zod-api/express-zod-api/src/integration-base.ts Lines 373 to 382 in 6346e26 This is another reason why I write my own implementation. I don't know what is doable about this ? In the end, is the defaultImplementation a good idea inside the client ? it could be a util function exposed in the package ?Here is my customImplementation derived from the default one, partially solving the upload issue, even though it could be optimized a lot it works: import { Client, Implementation } from './generatedClient';
export const buildAPIClient = ({
baseUrl,
token,
}: {
baseUrl: string;
token: string | null;
}) => {
const customImplementation: Implementation = async (method, path, params) => {
const url = new URL(path, baseUrl);
const hasBody = !['get', 'delete'].includes(method);
const hasParams = Object.keys(params).length > 0;
const hasFile = Object.values(params).some(
(value) => value instanceof File || value instanceof Blob
);
if (hasFile && !hasBody) {
throw new Error('Files cannot be sent without a body');
}
const searchParams =
hasBody && hasParams ? '' : `?${new URLSearchParams(params)}`;
const contentType = hasBody && !hasFile ? 'application/json' : undefined;
const formData = new FormData();
if (hasFile) {
Object.entries(params).forEach(([key, value]) => {
formData.append(key, value);
});
}
const body = hasFile
? formData
: hasBody
? JSON.stringify(params)
: undefined;
const response = await fetch(`${url}${searchParams}`, {
method: method.toUpperCase(),
headers: {
...(token ? { Authorization: token } : {}),
...(contentType ? { 'Content-Type': contentType } : {}),
},
body,
});
const responseContentType = response.headers.get('content-type');
if (!responseContentType) return;
const isJSON = responseContentType.startsWith('application/json');
return response[isJSON ? 'json' : 'text']();
};
return new Client(customImplementation);
}; About the type issuesI will create another discussion as it is not related to the Implementation, Integration and generated Client. Thanks for your response, hoping I can help make this project 1% better 😄 |
Beta Was this translation helpful? Give feedback.
-
I expect you to write your own implementation — it's absolutely fine.
So my goal is to keep the
Thank you, I will review what I could take from it to the default one, @Alexandregirbal |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi guys,
First of all, thanks for building this package, it's 99% amazing.
About the 1% left:
I just wanted to talk quickly about the way the default implementation is made and how one could make it better. It would be great to pass a baseURL to the Client instead of having to create a custom Implementation. At the same time, we could even consider adding some headers to pass to every request (like a jwt for example). What do you think ? I am keen to work on this to contribute to the project if you agree on.
I also wanted to say that this sentence in the Upload section made me run mad because I was adding the content type manually instead of letting my browser handling this for me. I could be great to add a note about it in the documentation:
Could become:
The request content type must be multipart/form-data, but no need to manually add this content-type to you request as it is handled by most browsers.
About the transformations in GET params, it's losing my generated client as it creates types undefined | undefined. it would be great to find a way to handle this natively and avoir transforms. I don't if this is in the todos.
Beta Was this translation helpful? Give feedback.
All reactions