-
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.fetch
andwindow.XMLHttpRequest
so 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 withfetch
andXMLHttpRequest
. 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
OkHttp
orAlamoFire
? - Is 100% compatibility with
XMLHttpRequest
andfetch
required? 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
NHttp
module? Is having a passive Http module as a default a deal-breaker for some applications? - How would
NHttp
work on the web if we extendedfetch
for 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)