-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
TL;DR?
We are planning on building a new Capacitor Plugin called NHttp based on the @capacitor-community/http plugin that patches fetch, XMLHttpRequest, and adds in new functions like download, upload, and other functions. Will be opt-in in Capacitor 3 and the default in Capacitor 4.0.
But please go and read! We'd love to hear the community's thoughts!
Challenge
Currently the window.fetch and window.XMLHttpRequest functions in a Capacitor application have the same limitations that they have in the browser. This includes, but is not limited to:
- CORS restrictions
- Unable to use certificate based authentication
- Unable to take advantage of parallel requests on multiple threads
These issues can be bypassed by using libraries such as @capacitor-community/http and cordova-plugin-advanced-http that use the native android/iOS http libraries to do web requests. But this introduces other problems:
- Third party libraries still rely on
window.fetchandwindow.XMLHttpRequestso you still aren't taking advantage of the plugins - You are restricted to using the plugin's APIs rather than using the existing browser APIs
- Http requests have to wait until the plugins have been loaded into the Capacitor runtime, which may lead to race conditions.
Both of these approaches have drawbacks. And auth providers such as Okta require workarounds that are not intuitive. Hence this proposal!
Goal
What are we trying to achieve?
- Create a plugin that is bundled with
@capacitor/core**that provides near 100% compatibility withfetchandXMLHttpRequest. This will be opt-in in Capacitor 3.x and the default (with an opt-out) in Capacitor 4.x. - Add performance improvements with multi-threading on the native layer without compromising compatibility with existing browser APIs.
- Create a solid base for more advanced http functions that will be bundled into the core runtime for additions in Capacitor 4.x.
Proposal
Built in Native-Http plugin (NHttp)
With NHttp, we can patch window.fetch and window.XMLHttpRequest to use window.Capacitor.Plugins.NHttp functions in order to get the fix the challenges listed above with using the existing browser functions. This allows third party libraries to use NHttp without developers needing to rewrite their code. It also allows Capacitor developers to use more web APIs while getting the benefits of native application code/performance.
NHttp will be bundled with @capacitor/core in a similar way that the WebView plugin is bundled/initialized with the core runtime. This allows it to be initialized at the exact time that the Capacitor bridge is initialized, allowing for all requests to use NHttp.
In Capacitor 3.x, we will add a new capacitor.config option tentatively called "useNHttp" that will default to false. This value will default to true in Capacitor 4.x. The following code snippet demonstrates how the APIs will be patched.
if (capacitorConfig.useNHttp) {
// Assign web fetch/XMLHttpRequest to another variable
window.webFetch = window.fetch;
window.webXMLHttpRequest = window.XMLHttpRequest;
// Patch fetch and XMLHttpRequest
window.fetch = window.Capacitor.Plugins.NHttp.fetch;
window.XMLHttpRequest = window.Capacitor.Plugins.NHttp.XmlHttpRequest;
}Deprecate @capacitor-community/http plugin
The @capacitor-community/http plugin, which is maintained by Ionic, will be updated to support Capacitor 4.0 and then deprecated. NHttp will have feature parity with @capacitor-community/http with the release of Capacitor 4.0. In Capacitor 5.0, the @capacitor-community/http plugin will not be updated and may not work with future releases of Capacitor.
Ionic will create a migration document for migrating code to support the NHttp plugin by providing code samples. An example of the migration guide would be something similar to this.
// old
const options = {
url: 'https://example.com/my/api',
};
const response: HttpResponse = await Http.get(options);
// new
const response: Reponse = await window.fetch('https://example.com/my/api')For extended functions that browser APIs don't cover, but the @capacitor-community/http plugin does, the syntax may look something similar to this.
// old
const options = {
url: 'https://example.com/download.pdf',
filePath: 'document.pdf',
fileDirectory: FilesystemDirectory.Downloads,
};
const response: HttpDownloadFileResult = await Http.downloadFile(options);
// new
const response: Response = await window.download('https://example.com/download.pdf', {
filename: 'document.pdf',
directory: window.Capacitor.Plugins.NHttp.getDefaultDownloadDirectory()
}If the community would like to continue maintaining the existing @capacitor-community/http plugin, please post in the comments!
Undecided
- Should we bring in external dependencies or use the built in Http libraries? Is the community ok with bringing in something like
OkHttporAlamoFire? - Is 100% compatibility with
XMLHttpRequestandfetchrequired? Should we aim for the same level of compatibility that https://github.com/github/fetch has? - Should we provide a harder opt-out that allows you to uninstall the
NHttpmodule? Is having a passive Http module as a default a deal-breaker for some applications? - How would
NHttpwork on the web if we extendedfetchfor users that are using Capacitor on Web as well as Android and iOS. - Are there any other modules that should be a part of core? Cookies, motion, haptics, etc? (Certain modules like Geolocation, Push Notifications, etc can't be included in core due to permissions)
