Similar to T89889, this RFC proposes a simple path to split presentation vs data by relatively small refactoring of the existing API to use objects instead of strings. More at https://www.mediawiki.org/wiki/Requests_for_comment/Business_Layer_Architecture_on_budget
Description
Status | Subtype | Assigned | Task | ||
---|---|---|---|---|---|
Duplicate | None | T93897 Better separate logic/data classes from API modules to encourage internal use | |||
Declined | Yurik | T95654 RFC: Business Layer Architecture on budget |
Event Timeline
RFC meeting: https://tools.wmflabs.org/meetbot/wikimedia-office/2015/wikimedia-office.2015-04-22-21.01.html
Meeting summary
- very little support for having all code doing SQL directly (gwicke, 21:09:36)
- http://bots.wmflabs.org/~wm-bot/logs/%23wikimedia-office/ (wm-bot, 21:31:11)
- AGREED: make RFC more focused, less preachy (TimStarling, 22:01:53)
- probably need another RFC meeting about this (TimStarling, 22:02:18)
Discussion held at Lyon, 2015-05-25.
Summary (please correct me if it's wrong or incomplete):
(click the image to see it the right way up)
Models:
- current (top left): web API modules and special pages contain redundant code. Both use SQL directly.
- Yuri's proposal (top right): Build UI based on internal API calls. Improve internal pseudo-web API interface. The internal API interface is "amourphous": from PHP's perspective, all calls use the same exact class/interface.
- Uncle Bob's version: Build UI and API as a thin layer on top of business logic (controllers, interactors), which use SQL (or, ideally, an abstracted storage layer). Interfaces are well defined in terms of PHP interfaces.
Positions:
Gabriel and Yuri favor internal API calls. Gabriel favors representing parameters and results as plain JSON-style arrays, Yurik wants to allow value objects like TitleValue for convenience and to avoid marshaling overhead.
- (+) Generic mechanism for batching, caching, and parallelism
- (+) Exposes all business logic per default
- (+) Little or no refactoring needed in the API modules
- (-) Amorphous interface misses out on all PHP language features (type hinting)
- (-) Business logic is tied closely to (abstract) representation logic (ApiResult)
- (-) Implement marshaling logic
Tim, Brad, Brian, and Daniel favor Uncle Bob's approach, in particular the notion that PHP code should use PHP concepts and PHP language features (interfaces, type hinting).
- (+) "Native" feel of the code, good integration with IDEs, Doxygen, etc
- (+) Business logic is isolated from representational logic, providing easy re-use and improved testability
- (+) Transparent remoting and caching is given by the option to implement service interfaces
- (-) Batching and parallelism would need to be made explicit, in the cases in which they are needed.
- (-) API moduels and UI modules (SpecialPages) need to be refactored to extract the logic controller.
Consensus:
- Business logic should be implemented only once
- SQL code for a specific purpose should be written only once
- UI code should be separate from SQL code
- Permission checks etc should be done in the business logic, and be separate from SQL and UI.
- UI and API should use the same paging mechanism
- everything that is accessible via the UI (e.g. QueryPages) should be available via the API as well.
- Having the ability to call the API internally is useful at least in some (possibly rare) cases
Disagreement/Questions:
- Should internal API calls be the preferred way of sharing logic between API and UI?
- How hard is it to make internal API calls easy, safe, and performant?
- Is porting UI modules to using the internal API much easier than extracting a controller and building the UI (and API) on top of that?
- Is Uncle Bob's model the ultimate ideal?
- Would Yurik's model be a good stepping stone towards on the way to Uncle Bob's model?
Next steps:
Code experiment to get an idea of the cost of refactoring
- implement passing TitleValue trhough ApiRequest and ApiResult
- implement an internal API call service (as opposed to the old static function)
- propose a re-implementation of a simple SpecialPage based on the new internal API interface
For contrast:
- extract a logic controller from a simple API module
- re-implement the API module and the corresponding SpecialPage on top of the new controller
Decline as per discussion at the Hackathon in Leon documented above. Now clarified by T169266: Clarify recommendations around using FauxRequest.