Description
I need to send the authentication cookies in every request to the REST API made with @frontity/wp-source
.
Examples
I want to request /wp-json/wp/v2/users
and get a full list of users if I’m authenticated as an admin.
Possible solution
One way to solve this is passing a fetch
options object as a parameter to libraries.source.api.get
so I can use fetch
with { credentials: "include" }
to attach cookies to the request. (This solution won’t work with the default handlers, only with those created by users that decide to pass the options object to api.get
)
Another possible way is to set a general option in wp-source
state like allowCredentials: true
and the libraries.source.api.get
should use that option to set the credentials value to "include"
, which is the value that allows the cookies to be shared between subdomains.
I am designing the version 2 of source
packages right now and I am actually thinking that we should remove libraries.source.api
in favor of a helper like:
import { getApiUrl } from "@frontity/wp-source/helpers";
const myHandler = ({ state, options }) => {
const apiUrl = getApiUrl({ state, options });
const response = await fetch(apiUrl);
};
That way you won’t have to build the URL yourself but you get to do the fetch
yourself, and have more control over it.
import { getApiUrl } from "@frontity/wp-source/helpers";
const myHandler = ({ state, options }) => {
const apiUrl = getApiUrl({ state, options });
const response = await fetch(apiUrl, { credentials: "include" });
};
The apiUrl
returned by getApiUrl
can be a URL object, which is accepted by fetch
. Maybe something like this:
const getApiUrl = ({ state, options, api, endpoint, params }) => {
// Use options.api or the default.
const base = api || options.api || state.source.api;
// Use options endpoint or the default.
let endpoint = endpoint || options.endpoint || state.wpSource.default.endpoint;
// Add /wp/v2 to endpoint if needed.
if (!endpoint.startsWith("/")) endpoint = `/wp/v2/${endpoint}`;
// Join them and make sure there are no repeated /.
const api = `${base}/${endpoint}`.replace(/\/+/, "/");
// Build the URL object.
const url = new URL(base);
// Add the params.
const allParams = ({
embed: true,
...state.wpSource.default.params,
...options.params,
...params
})
Object.keys(allParams).forEach(key =>
url.searchParams.append(key, allParams[key])
);
return url;
};
Other packages like wp-graphql-source
will have their own helper to build the API URL.
Two questions:
- What do you think about this approach?
- Can you use
fetch
manually instead of libraries.source.api
for now?
I created this topic with the intention of starting a discussion about it, but I have no preferred way to solve this issue.
The helper looks good to me. I was wondering if api.get
had to exist in the first place, because we’ll run soon into a situation where we need to extend every HTTP method like api.post
and having to maintain that doesn’t make sense I think.
I don’t understand completely the getApiUrl
function though. What is options
and params
? Is options
part of a refactorization of the handlers API?
Yes, I wasn’t actually planning on using api.get
that much because most of the cases where I want to be authenticated are POST
requests, so I already needed to use fetch
.
EDIT: I’ve updated the topic title.
Awesome! Thanks for your input @orballo
Yeah, sorry, I’m thinking already with the new API. I’ll open the Feature Discussion for Source v2 as soon as I can
Basically, you could configure the handler in the state
like this:
export default {
state: {
source: {
handlers: {
home: {
pattern: "/",
options: {
type: "archive",
endpoint: "posts"
}
},
category: {
pattern: "/category/(.*)?/:slug",
options: {
type: "taxonomy",
endpoint: "posts",
taxonomyEndpoint: "categories"
}
},
...
}
}
}
}
That way people will be able to configure the handlers with their frontity.settings.js
file:
const settings = {
state: {
source: {
handlers: {
home: {
pattern: "/blog"
}
}
}
}
};
Or even create new handlers without writing code:
const settings = {
state: {
source: {
handlers: {
weirdCategory: {
pattern: "/weird-category",
options: {
type: "archive",
endpoint: "weird-post-type",
params: {
per_page: 50,
categories: "123,456,789"
}
}
}
}
}
}
};
This is a super brief example of the new Source v2 API, it has much more
1 Like