There has been a good deal of buzz around using APEX for Progressive Web Apps (PWA) lately thanks to the excellent work and presentations by Vincent Morneau. You can and should read his Turning APEX into a PWA document. Here I want to share my thoughts on building PWAs with APEX; the possibilities, limits and challenges. This post is less researched and more quickly written than most of mine but not really shorter. It is not based on any actual implementation or hands on investigation. As a member of the APEX development team I must emphasize that this contains my own opinions. Any forward looking statements about APEX are purely speculative and not part of any official statement of direction.
Vincent has pointed out that Interactive Grid and Interactive Report do not work offline and cannot be made to do so because they internally make ajax calls to the server. This is true but it is just the tip of the iceberg. The following are some of my bigger concerns.
APEX is multi-tenant and this works against the web’s same-origin policy. Consider apex.oracle.com, APEX sees it as 38,000 some odd workspaces and 100,000 plus web apps but the web sees one web app. APEX and the Oracle Database keeps all the workspaces and their schemas isolated. But on the browser there is no built-in separation. The browser considers all the apps from all the workspaces on an APEX instance to be one, which means it assumes they all trust each other. So browser features like named windows, Local/SessionStorage, and IndexedDB will let any app access the data of any of the others. This has serious security and privacy consequences. APEX has APIs such as
apex.storage.getScopedSessionStorage to keep apps from stepping on each other but it is advisory only; it cannot be enforced. (Note you don’t have to use these browser features.) Because an offline PWA uses IndexedDB something will be needed to keep apps separate. Either some web-tier magic is needed so the apps are in their own origin or you have to deploy one app per APEX Instance. Perhaps there is something that ORDS can do to help. I don’t know. I should point out that this issue is not unique to APEX but would apply to any multi-tenant web platform.
PWAs require specific files to be at the root of the web URL. APEX doesn’t provide direct access or control over the web tier. It may be that creating a PWA will always require configuring the web server. Again ORDS may be able to help.
Vincent describes the “app shell” as the set of resources that need to be cached. This is where the APEX architecture works against the PWA in a fundamental way. APEX page resources mix data and static/structural presentation. Server side conditions and other logic affect what parts of a page are rendered. This means that the same page resource can be, and generally is, different each time it is requested. APEX pages are not a shell they are the whole egg (or turtle?). Think about a simple address book app. The address edit detail page as rendered by the APEX engine would contain input fields (page items) for things like name, address and phone number but these fields would also have values based on the current entry being edited. The field values are not part of the shell. In addition the page may be used for both edit and create in which case there is likely some server side conditions to choose between rendering a create button or an update button. If this page resource gets cached you have also cached data for a particular entry. When it is time to use this page offline you need to write code to replace the values with the actual entry data to be edited. Or you have to cached a copy of the page for each entry. If you go this route it is not really a shell that is being cached.
APEX has made some architectural changes in this area. In release 5.1 Interactive Grid introduced a client side data model. This separates the data from the presentation. The data is fetched from the server as JSON, stored and manipulated in the model, and presented and edited in the IG UI. The binding between the model and various views such as grid, single row, icon, detail and chart is handled automatically. (Note: the fact that the JSON can be part of the page resource is an optimization that can be turned off.) The APEX JET Charts also have a data model as this is a necessary part of using JET visualizations. I hope that this architecture is used more going forward.
Although currently IG cannot be used in a PWA mainly because of the ajax requests associated with saved report settings, architecturally it is in a better position than most other parts of APEX to support offline PWAs in the future. This is because of the separation of data and presentation. What needs to be done is to switch between the APEX server and indexedDB according to online status for saved report settings and to synchronize the settings. The local report settings would also be used when fetching offline data from indexedDB into the IG model layer. These are changes that APEX would have to implement. However the modular components that make up the Interactive Grid region such as the model and grid widget could potentially be useful in a PWA today. I say potentially because I have not tried it yet. The question is does the model API have the necessary methods for fetching and saving the data in indexedDB. I am very open to improving the APEX model layer in this area.
This sounds hopeful for the future of Interactive Grid but what about other parts of APEX? The model is designed to handle forms (a single record) and trees as well as reports. These are not currently exposed in any APEX region but you may be able to do it yourself. Keep in mind that for reports the model and tableModelView widget can do just about anything that Classic Reports can do and in a way that keeps the data and presentation separate. The IG Cookbook has an example on page IG Cards that demonstrates a card style report. This could also be done with a model and tableModelView cutting out the IG region to avoid its current PWA unfriendly behavior.
Currently saving the APEX model only works with the Interactive Grid. I hope this changes in the future. Either by making it possible/easy to create your own DML process for your model based region plug-ins or not hard coding the Automatic Row Processing (DML) process to the Interactive Grid region. See the IG Cookbook Tabbed Record Editing page for an example that uses the model and simple two way data binding.
If protected values are stored locally such as in indexedDB while the app is offline even if the checksum is also stored it may not be possible to successfully save the data back to the server once the app is online again. It depends on if a new session is established when going back online. Buried in this whole concern over session state is the question just how will sessions be maintained and reestablished by APEX PWAs?
I gave a very simple example but checksums are used in many places in APEX including on URLs, URLs that open dialog pages, and interactive grid model data. How session state protection behaves or could behave when there is the possibility of going offline requires much more thought and investigation. Simply turning it off every where in your app just to support offline should not be done without carefully considering the security implications.
My final though is synchronization is hard. Simply saving and replaying ajax requests is not data synchronization. If you add a contact to your address book while offline and then delete it while still offline, it makes no sense, once back online to send a request to add and then another to delete the contact. The same is true if contacts are edited multiple times. The database just needs to be synchronized to the final state. And the synchronization goes both directions updating the server with changes made while offline and also updating the client with the latest data from the server. I also feel that in an APEX app you shouldn’t need to define separate web services to support offline use. There is no reason why ajax calls can’t be made to APEX. Ideally this would leverage the normal APEX ajax code paths. If using the APEX model this includes validation. A big part of the app design for offline is going to be deciding what data to make available offline. It is probably unwise to replicate the entire database into indexedDB. Perhaps just the user’s data, or just the data from the last few days or weeks, or just data related to a specific project etc. The user may choose what to make available offline or perhaps whatever they have been looking at most recently is transparently written through to indexedDB. There are so many possibilities. When you do synchronize there can be conflicts. APEX already has built-in support for detecting conflicts using either row values or a version column. However the longer the time between fetching the data and saving it means the more chance for others to make conflicting edits. It will be even more important to provide ways for the user to correct the conflicts and save without having to completely redo all their changes.
Many of my concerns have been about offline use but as Vincent points out offline is only one piece of what it means to be a PWA. The main aspects of a PWA are:
- Installable: The app can be installed and resources cached for better performance. This is progressive meaning that the web app still works without being installed or on browsers that don’t support PWAs. Being installed makes the web app feel more lake a native app with features such as a home screen icon, full screen etc.
- Responsive: The app works well in different form factors from phone to desktop. Universal Theme is already good at this. There are specific region types like the Reflow Report designed to be responsive and ideally we will continue to improve responsive capabilities throughout.
- Offline: The app can still work when there is no network connection. How much of the app can be used offline is going to depend based on app purpose, user needs, and effort to make it work. There is always going to be some effort involved in making this work. It is not clear to what extent APEX can make this easy/declarative and for which use cases.
- Notification: Web push and notifications API allow the user to receive notifications from the app even when it isn’t running. APEX has good support for sending emails but who uses email these days? Well I still do but some users may prefer this.
When you are telling the APEX team you want PWA support be specific. Let us know what aspects of PWA technology you need the most.
So will this happen; will APEX support some or all aspects of PWA technology? If so which and when? Should we even bother? I hear some people say this isn’t even something that APEX needs to support; let other frameworks worry about that. Often it is a specific statement about offline and how the world is getting ever more connected. This may be true but there are exceptions. The web site Mountain Project is a good example of where offline is useful. It is a guide to outdoor rock climbing and many rock climbing areas do not have Internet access. It is not a PWA but instead has an app for Android and iOS. It could have gone the PWA route I suppose. Before you head out to the crag you download the area of interest and then the app works while offline giving you all the climbing route info.
I have no idea to what extent if any APEX will embrace PWAs but I do have an opinion. I think that it should if for no other reason than I believe that APEX should be able to do anything that other web platforms/frameworks can do. It could be that in the future being a PWA is simply what is expected when you claim to have good mobile support.
Let us know your Progressive Web App use cases and needs and how you would like to see APEX support them.