User:Daniel Kinzler (WMDE)/FauxRequest

This page is a position paper representing the view of ArchCom (currently, only Daniel's view) on the use of FauxRequest to perform in-process calls to the MediaWiki web API.

Use of FauxRequest in Tests
FauxRequest was created to allow the emulation of API calls in tests, particularly integration for API modules. This usage is uncontroversial.

Advantages of Using FauxRequest in Production Code

 * No extra effort needed to using an existing API module internally
 * No extra effort for switching from an internal call to a remote call
 * Internal and external callers use the exact same interface
 * Batching and prallelization are possible everywhere

Disadvantages of Using FauxRequest in Production Code

 * Forces PHP code to use an amorphous "stringly typed" interface. This prevents statical analysis from spotting errors, and from providing contextual help and auto-completion in an IDE.
 * Forces application logic to call services in a non-ideomatic way, requiring extra code for parameter passing and error handling. Essentially, it forces a coding style that is similar to constantly working via reflection instead of using language features directly.
 * Marshalling of parameters and results adds overhead (computational and memory).
 * Even if marshalling of some well known objects (Title, User, etc) was skipped for internal calls, other constructs would still need special handling.
 * Bypassing marshalling for such objects would make the complex code in ApiBase even more complex.
 * Removes an incentive to separate application logic from I/O and presentation. Ideally, API modules should be thin wrappers around service objects or some sort of controller or "interactor" which knows nothing about API parameters or result formats.
 * isolating application logic from I/O and presentation allows for proper dependency injection, proper unit testing, and easy re-use (e.g. for the implementation of a Special page)

Discussion
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

Rebuttal of advantages
 * re "No extra effort needed to using an existing API module internally"
 * Initial implementation becomes easier. Reading, maintaining, and refactoring the code becomes harder.
 * re "No extra effort for switching from an internal call to a remote call"
 * It's no extra effort because this approach makes all calls harder to both read and write.
 * re "Internal and external callers use the exact same interface"
 * Framework isolation is a good thing
 * Isolating logic from details of transport and encoding is a good thing
 * Adapters that allow access to remote services in an idiomatic way are a good thing
 * re "Batching and prallelization are possible everywhere"
 * Batching/parallelization and remoting should be explicit, to avoid hidden cost and similar surprises
 * this would be the CORBAfication of MediaWiki.

Rebuttal of disadvantages
 * TBD

Conclusion

 * Using FauxRequest in Production code may be acceptable as a short term solution, but should be considered tech debt that needs to be addressed in a timely manner.
 * Application logic should not be exposed to any details related to transport or encoding for external calls.
 * Application logic should only interact with value objects, service objects, domain entities, and similar representation of the domain model idiomatic to the programming language used.
 * The same service interface can be implemented to act locally or to call out to a remote server, possibly using the MediaWiki web API or the RESTbase interface.
 * Such a service could but should not be implemented based on a FauxRequest. Instead, the API module in question should be implemented on top of the respective service interface.