We need some element, some layer between the CheckConstraints API class (and also SpecialConstraintReport) and the current DelegatingConstraintChecker, where we can introduce the caching.
Input: A list of entity IDs and statement IDs to check, along with an optional list of constraint IDs to filter for (otherwise: check all constraints). Or, much more elegantly: a ConstraintCheckPlan encapsulating all that, if we pull T180796: Add ConstraintCheckPlan class into this task.
Output: A JSON blob (as PHP array structure, not string) of constraint check results. We could also return a list of CheckResults, but that would mean that in the most common case (API request with cache hit), we would deserialize those CheckResults from the cache only to serialize them into JSON again immediately, which seems rather unnecessary to me. I’d rather return JSON at this level directly, make the API simply pass it through, and update the special page to operate on the JSON instead of a CheckResult. (We still have a JSON string → PHP array → JSON string roundtrip, but that can’t be avoided since the API request might also have requested XML results.)
If we do implement T180796: Add ConstraintCheckPlan class as part of this, then I think we could just turn DelegatingConstraintChecker into this layer. Its current interface (checkAgainstConstraintsOnEntityId, -ClaimId) doesn’t make too much sense in the presence of ConstraintCheckPlan anyways.