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
Direct communication with external API #1417
Comments
I didnt checked in detail - but i liked the initial idea of defining a hash in the fetch method instead of using the url as identifier So we have different ways to accomplish this i can think of
fetch.customHash('myCustomHash')('/my/endpoint/url', {...}) probably one of the ugliest ways
import {hashedFetch} from "svelte";
hashedFetch('/my/endpoint/url', {...}, 'myCustomHash')
{
kit: {
fetch: {
prependHost: 'http://10.0.10.3:1337/'
}
}
} While this could be a good solution, whats about when different Hosts should be prepended.
export function interceptServerFetch(url, params, fetch) {
if(url.startsWith('/')) url = 'http://10.0.10.3:1337' + url;
return fetch(url, params);
} While fetch is often used in load, option 1 and 2 will leak this information to the browser. version 5 feels superior IMO |
I like 5 also but it has two issues:
In the same time 5 will be very easy to implement. |
You could do this in any way you like, but keep in mind, the url has to be valid for CSR. You're gonna define if its replaced, concatinated or something like this export function interceptServerFetch(url, params, fetch) {
if(url.startsWith('/api/')) url = 'http://10.0.10.3:1337/' + url.substr(5);
return fetch(url, params);
} about not so flexible - I guess I have to disagree. The only thing thats not possible is to give two different urls the same hydration. |
But to fit more your example you wanna do something like this export async load({fetch}) {
let res = await fetch('https://api.domain.com/endpoint');
....
}; hooks.js export function interceptServerFetch(url, params, fetch) {
url = url.replace('https://api.domain.com', 'http://10.0.10.3:1337');
return fetch(url, params);
}``` |
Ok, it's looking good enough and easy to implement. |
That's basically what Rich had suggested in #1406 (comment) with his |
@Rich-Harris then can I try to implement it? |
Yeah I did it more aggressive returning a promise like the normal fetch method. this way, its also possible to resolve it on different ways like unix sockets, file reads or other socket connections |
Oh, the custom /**
* @param {RequestInfo} info
* @param {RequestInit} init
* @returns {Response}
*/
export async function serverFetch(info, init) {
// potential footgun: RequestInfo can be a string or a Request object with a url property
// — people would need to decide for themselves whether to accommodate the latter
const data = await get_data_somehow(info);
return new Response(data); // https://developer.mozilla.org/en-US/docs/Web/API/Response/Response
} There's no need to pass |
Isnt the fetch method (given by load (context module)) needed to simulate the "user" request? |
I don't understand? |
To transport the headers of the initial request of the browser to the endpoints, like cookies/sessionIDs and so on? |
The |
There's an issue around browser-sent request headers here: #696. I think what we'd need to do here is take the initial So perhaps the interface is actually more like this, which conveniently deals with the footgun mentioned above: /**
* @param {Request} req
* @returns {Response}
*/
export async function serverFetch(req) {
const data = await get_data_somehow(req.url);
return new Response(data); // https://developer.mozilla.org/en-US/docs/Web/API/Response/Response
} |
I think creating a Request object each time is a good idea instead of trying to use |
In reviewing #1465, I think there's a difficulty with the proposed API, which is that SvelteKit does not call One difficulty with extending it to work on the internal API is that we'd lose the performance optimization. E.g. consider the code below. It would call the
Something akin to @Rich-Harris's earlier Perhaps we can modify the
|
@benmccann I suppose this optimization for "requested resource in-process" not so important here, much more important it provides serialization to avoid double load on the browser side.
It's can work if we will do serialization outside this function. For that, we should split our server fetch function. If you want I can provide this type of PR. But can I hear @Rich-Harris opinion? |
Rich pointed out to me that my use case of redirecting fetches on the same domain to another location (e.g. app server written in another language) can already be done with
|
The main idea is getting a shorter path to API from SSR and CSR without extra hops and proxies.
For that, we should have different server URLs and client URLs for the same resource ID. Even now you can have different URLs for
fetch
between server and client but our serialization system detect resource by the whole URL and produce double request in that situation.This feature request is not something new and several times accrued in Sapper tracker for example sveltejs/sapper#489
Also, I did some rouge PR for this here #1406, and you can find some extra details there.
It looks like we should more detail describe this feature and cases to make a clean solution.
It's a little confusing theme, but I want to hear your opinions and ideas.
The text was updated successfully, but these errors were encountered: