WebExpress 2.0.0‑alpha – Introducing the New View–State–Service Architecture
With the new View‑State‑Service architecture, WebExpress enters a phase in which client‑side behavior becomes clearer, more predictable, and better structured than ever before. The motivation behind this step is straightforward. The previous mechanisms, scattered state, direct DOM manipulations, and implicit service calls, have worked well over the years but reach their limits once more complex interactions, multiple dependent components, or reusable patterns emerge. The new architecture establishes a clear foundation that remains consistent for both simple controls and sophisticated applications, while being authored entirely in C#.
At its core, the model separates the three responsibilities that repeatedly occur in modern web applications. The state holds all data and UI flags of a control and serves as the single source of truth. The view is a pure function of that state and generates the DOM without its own side effects. The service encapsulates all network access and returns normalized results. These three roles are connected through a clear unidirectional data flow that extends from initialization through user interactions to re-rendering. The C# layer remains the origin of all definitions. It creates the initial state, describes the services, and defines which actions and bindings lead to which intents. JavaScript serves solely as the engine that executes these specifications.
For authors working in C#, this primarily changes how state and behavior are described. Instead of scattered properties, an explicit state object emerges, fully serialized within a data-wx-state island. Services are no longer configured implicitly or through JavaScript but are defined as typed descriptors in C#, including routing, parameter mapping, and response structure. Bindings and actions retain their familiar surface but internally produce intents that modify the state or invoke services. The view can still be rendered server-side, optionally as a template or as a declarative structure reconciled by the client. The result is a predictable, testable, and extensible model that integrates seamlessly into the existing WebExpress ecosystem.
To make these changes tangible, it is worth looking at a small but typical example from everyday WebExpress development. In the past, a simple list was usually configured through scattered properties. The developer set the page, page size, and perhaps a search term directly on the control, while the actual data retrieval occurred implicitly within the framework or JavaScript. The logic was functional but not visibly consolidated or recognizable as a coherent process. A control might set the page to null, the page size to fifty, and the search string to empty, while the endpoint and parameter mapping were defined elsewhere or even in JavaScript. The behavior resulted from multiple places that were not necessarily perceived as a unified model.
With the new architecture, this picture changes fundamentally. The same list is now fully described in C#, as a clearly defined state, a declarative service, and a set of intents that govern behavior. The developer defines the initial state as an object placed in a data-wx-state island, defines the service as a typed descriptor specifying routing, parameters, and response structure, and describes interactions as intents that can both modify the state and call services. The list thus becomes a transparent, testable, and predictable building block whose behavior derives entirely from its C# definition.
A simple example illustrates this clearly. Previously, a list might have been initialized like this:
new ControlRestList("myList")
{
Page = _ => 0;
PageSize = _ => 50;
Search = _ => "";
RestUri = _ => new UriEndpoint("/api/games");
};
Today, the same component looks like this:
new ControlDataList("myList")
.State(s => s
.Page(0)
.PageSize(25))
.DataService<MonkeyIslandGamesList>();
The difference is not merely syntactic but conceptual. The earlier approach described a list, while the new approach describes a model. The former scattered knowledge across multiple places, while the latter consolidates it into a single, well-structured definition. The old approach left many implicit decisions to the framework, while the new one makes them explicit and therefore verifiable. Most importantly, the old approach was difficult to test, whereas the new one, with state, reducers, and effects, provides a clear foundation for automated testing.
With this architecture, a new chapter begins that not only brings technical clarity but also opens space for collaborative evolution. Many of the new concepts are deliberately designed to be open, allowing them to grow in real projects and be refined through feedback from practice. Anyone wishing to contribute is warmly invited to share ideas, suggestions, issues, or extensions. Every contribution helps sharpen the model and advance WebExpress as a modern, robust, and community-driven framework.

Comments
Post a Comment