User:Daniel Kinzler (WMDE)/Frontend Architecture

This document describes how MediaWiki's user interface should function. It is intended to provide constraints and guiding principles for feature development.

The front-end architecture defines the flow of information and control between the client device and the application servers (or, more generally, the data storage layer). In practice, this mostly mostly means defining when, where and how HTML is generated, manipulated, and assembled.

Assumptions

 * 1) MediaWiki has to be installable on a plain LAMP stack without root access (shared hosting use case).
 * 2) We cannot reply on being able to run PHP and JS code in the same process / without the need for communication via the network stack (no v8js in PHP).
 * 3) Eventually, we want to allow fully data driven UIs (meaning that all HTML is generated on the client). This requires all functionality to be available via an API.
 * 4) However, we want to support at least consumption of all content, including meta-data, on HTML-only devices with no JS support.
 * 5) We want the ability to serve different HTML to different classes of clients (varying on screen size, accepted language, etc), and make full use of CDN caching when doing so.
 * 6) URLs for different renderings (languages) of content should be different, while different presentations for various devices should share a URL.
 * 7) However, we also want the ability to serve reactive content to the client which adapts to the target device's capabilities.
 * 8) We cannot assume that all functionality can be converted to a data driven approach right away, it will take some time for e.g. all extensions to be converted to a data driven approach. We need to cater to transitional stages. We aim to make the most common workflows available via APIs soon.
 * 9) We'd like the ability to render declarative templates on the client as well as on the server.
 * 10) We want consistent localization when rendering on the client or on the server, including message strings, parameter substitution, plural handling, and formatting for numbers and dates. For now, the single source of truth for this is the existing PHP code, but maintaining a full JS port of this code should be considered, since proper data-diven UIs are blocked on this.
 * 11) We are not aiming for a single page application approach for MediaWiki. However, we want single-page applications to be possible based on our APIs, which in theory provides the same functionality as the default UI.
 * 12) We want full Multi-Data-Center support. This means all information that is needed to decide whether a request needs to be routed to the master DC needs to be in the request. For the application servers, this mostly means "don't write to the database in GET requests".
 * 13) We want a single source of truth for rendering wikitext (and any other content type) as HTML.

Components
The following classes of things generate HTML and need to be considered below: Skin, ContentHandlers, input forms for Special pages and action handlers, results (listings) on for Special pages and action handlers, dynamic content for some page types (file pages, category pages).
 * Page composition at the network edge (probably using ESI). API for serving HTML snippets (some cacheable globally, some per user, some not at all)
 * This should be used at least to combine the parts of the skin with the page content.
 * Usage of this mechanism is optional. The index.php entry point still needs to deliver a fully composed page per default, so MW is usable without an ESI capable caching layer.
 * This requires a dependency tracking and puring engine (using Kafka as a bus and some graph database for storing the dependency graph). Used to re-generate HTML snippets (and other derived artifacts).
 * It would perhaps be useful to support additional massaging/hydration, beyond what ESI supports. This would allow use to do localization here, as well as adapt for client devices.
 * ESI requires that the caching layer needs to be able to predict what kind of content it will be getting by looking at the request. This means e.g. that Special pages that serve non-HTML output would not be possible or would have to be especially registered.
 * Template engine with a JS and a PHP implementation.
 * Only if we have localization implemented in both JS and PHP, templates can be fully data driven.
 * If we have PHP code as the single source of truth for i10n handling, templates can only use pre-formatted data.
 * This would probably require an API mode that doesn't return abstract JSON nor rendered HTML, but some kind intermediate form (which may be annotated HTML).
 * Rendering special pages can be HTML based or data driven.
 * HTML based special pages should generate annotated HTML, somewhat similar to the output of Parsoid, that allows easy massaging for different target devices.
 * Data driven special pages just apply a template to data - on the server, the data would be generated by an internal API call. On the client, it would come from a REST API. Input forms would also be generated by a template.
 * A common REST API interface for functionality implemented in PHP, JS, or whatever other language.
 * Clients should not be aware of where and how an API is implemented.
 * Routing should be possible in the CDN layer / load balancer.
 * Routing should also be possible inside MW core, so it is available without a CDN layer.
 * JS framework that maps between a data model and the DOM, and manages API calls to the backend.
 * This kind of framework is designed for a fully data driven environment, with all rendering done in JS.
 * However, we will still have HTML snippets coming from the backend. At the very least for rendered page content. These snippets need to be integrated into the DOM, and they may need massaging/hydration.
 * Also, we may not be able to do properly localized formatting on the client. This means either calling back to the API for rendering, or getting pre-formatted data right away.
 * A single REST API for rendering page content, particularly wikitext, which yields output similar to the output of Parsoid.
 * This should probably be backed by a PHP-based parsoid port, to avoid calling back from JS to PHP code for each template, parser function, etc.