Page MenuHomePhabricator

RFC: Business Layer Architecture on budget
Closed, DeclinedPublic

Description

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

Event Timeline

Yurik raised the priority of this task from to Needs Triage.
Yurik updated the task description. (Show Details)
Yurik subscribed.

Can we talk about this in next week's RFC meeting?

Yes, was about to ask you))
I will write up some examples

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)

Scheduled meeting for Lyon Hackathon, Monday, 10:00.

Discussion held at Lyon, 2015-05-25.

Summary (please correct me if it's wrong or incomplete):

Hackathon2015-InternalAPI-20150524_160152.jpg (1×2 px, 2 MB)

(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
daniel closed this task as Declined.EditedNov 3 2017, 12:09 PM

Decline as per discussion at the Hackathon in Leon documented above. Now clarified by T169266: Clarify recommendations around using FauxRequest.