-
Notifications
You must be signed in to change notification settings - Fork 604
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
Isomorphic SDK support #38
Comments
@pi0 I agree that is an important feature, however, I am also a huge fan of Sindre Sorhus's work so I would advocate for either:
import ky from 'ky'
const notion = new Client({
requestClient: ky,
auth: process.env.NOTION_TOKEN,
}); |
It looks like ky allows providing one's own fetch function compatible with the browser API. I don't feel like ky provides a huge benefit over fetch - it's not so hard to write one's own wrappers around the API if need be and less abstractions usually means easier debugging in my experience. I think passing in a fetch function is a good pattern though. |
thanks for the kind words and for kicking off the discussion. it sounds like there's a few ways we could go about this. @pi0 i'm not too familiar with all the packaging concerns across Deno, Cloudlfare workers, and the other JS runtimes available. But just from an ES Modules perspective, I'm not sure the multi-target bundle (where we use import specifiers like the idea @taylorjdawson put forward seems a bit simpler to me. are there any disadvatanges to that approach? for example, if i'd like to use i still see usage on the backend with Node as the primary use case for this package. the Notion API wasn't really designed with client side application uses in mind. but i'm open to some of these ideas because it sounds like there's some exciting possibilities here. |
Thanks for inputs @aoberoi @b-zurg @taylorjdawson 🙏 So basically the proposed change is to make library depending on native Fetch API. This works out-of-the-box and without polyfills for almost every modern javascript runtime that already supports whatwg/fetch. // Works for browser, web-worker, CloudFlare workers and Deno
import { Client } from '@notionhq/client'
const notion = new Client({ }) Well, with exception of NodeJS! [^1] [^2] We can add a new option as of @taylorjdawson suggestion to provide HTTP client (a fetch-compatible library): // Alternatives: node-fetch, cross-fetch, isomorphic-fetch, undici-fetch
import fetch from 'node-fetch'
import { Client } from '@notionhq/client'
const notion = new Client({ fetch })
// or more advanced with options
// const notion = new Client({ fetch, fetchOptions: { agent } }) But since probably majority of sdk users are NodeJS users, we can also provide a shortcut with preconfigured instance of fetch polyfill: // Works with NodeJS (and bundler support for browsers)
import { Client } from '@notionhq/client/node'
// or CommonJS
const { Client } = require('@notionhq/client/node')
const notion = new Client({}) [^1] Unless it is already global polyfilled. Frameworks like Nuxt.js, do this by default so
Actually, it should extended package compatibility from NodeJS/CommonJS to universal ESM + NodeJS/ESM+CommonJS + Deno.
In many ways it makes sense. Isomorphic support allows supporting more backend runtimes like Deno that are probably closer to notion-api usage intention while browser usage might be tricky especially when it comes to passing a token. But if we support a consistent SDK client, we can use methods like using SDK in-browser via a backend proxy to solve security concerns and opening new possibilities.
I would say It depends on how much of it's features we need. As @aoberoi and @b-zurg mentioned, it probably costs more tree-shaking (and potentially Node runtime dependency). KY-universal is also discouraged by the maintainer. |
Before we build out support for more JS runtimes, I'd like to understand some of the use cases a bit more. One question I have is, do we really have use cases for Cloudflare workers and/or Deno right now? I've created #60 to organize some conversation around browser support specifically. I think we might need to set some expectations around that topic because sharing tokens with a browser application is probably something we should not advise until the Notion API's token model is designed for that (no promises). I don't mind keeping this issue open because it's already captured some great input. @pi0 @taylorjdawson @b-zurg is there a specific target you're most interested in? or are we more interested in increasing the possible adoption of the Notion API proactively? |
@pi0 @b-zurg Thanks for your valuable input! @aoberoi I like the idea of creating separate issues for separate runtime support and that browser support should (probably?) be prioritized If you wanted to go the route of not using a library that is both node & browser compatible then I like @pi0's original idea of having I would say since this was designed to be used more on the backend that node.js user would have the least amount of friction and let the browser users import something like |
@aoberoi I for one look forward to using this SDK with Deno. The use cases for Deno are mostly the same as Node, given that it's supposed to be a replacement (kind of), so anything for server-side JS/TS. It's just a shame that the incompatibility with browser/Deno/etc. is "just" due to a technical dependency like |
I took a look at I decided to go with |
Hi, thanks for the discussion folks, isomorphic support would be a great addition to the SDK. I built the node & browser bundles locally, but it looks like notion api does not allow CORS. Here's a 400 response from notion api on my preflight request:
Would it make sense for Notion API to allow CORS so it can be used in the browser directly? |
@xg-wang - It would not as it poses a security risk by when credentials are exposed in client-side requests. |
+1 I vote for having a
|
I echo what @pi0 commented, the benefits of enabling an isomorphic version for ESM are highly valuable. I was trying to fetch a database from my Notion to a Vite + Vue app, and have the same issue as here #209, that means that I will need to do a handmade version of the client with Axios. Although now getting problems with CORS. I hope this solutions go forward |
+1 for Deno |
This issue is mostly fixed by the Running into one more issue, though, which I’ll leave here for posterity in case someone else runs into what I had. The The best workaround is to patch your |
Can you provide a small code sample on how you got this working? I am trying to fetch some data from notion |
@rajeshg Um, sure. const notion = new Client({ auth: process.env.NOTION_TOKEN, fetch: fetch }); That’s assuming you’re in an environment that has a fetch-API-compatible const fetchWithMutableResponse = async (
url: Parameters<typeof fetch>[0],
init: Parameters<typeof fetch>[1]
): ReturnType<typeof fetch> => {
const responseOriginal = await fetch(input, init);
return responseOriginal.clone();
};
const notion = new Client({ auth: process.env.NOTION_TOKEN, fetch: fetchWithMutableResponse }); (Although in Workers you don’t have Does that make sense? I was not totally sure what you were asking. If you meant to ask about patching NPM packages, just run |
Hey! Congratulations on public notion API and awesome work on minimal and typed js SDK 💯
As of the current version, this package seems to only work with node.js, which makes missing lots of opportunities for supporting non-nodejs environments such as Deno, Cloudflare workers, universal frameworks like Nuxt.js , and frontend libraries like vue-notion this can open LOTS of new opportunities for using sdk.
For this change, we need to avoid depending on
got
and using a universal alternative (fetch
) API. Sincerequest
is already refactored, it would be easy to allow providing custom client implementation or creating multi-target bundles (see ohmyfetch as an example) that importing@notionhq/client
be as is now but having@notionhq/client/isomorphic
import (or/node
import) that is preconfigured with either node-fetch or got or faster node clients like nodejs/undici / undici-fetchI can propose a PR if above seems reasonable for purpose of notion-sdk.
The text was updated successfully, but these errors were encountered: