This is to gather some thoughts around this topic.
The background is that we use apipie to describe our REST API. It adds descriptions and (optional) validation.
In many places we use the EnumValidator. IMHO that validator is great because it also generates a nice description to the user of valid values. One common problem is that the data is actually dynamic where the EnumValidator
will store a copy of the concrete list.
In practice this means the application starts up and loads the data. Concrete examples that recently popped up:
Here for the resource_type
parameter it calls Permission.resources
, which is this method:
We saw the failure there when the test database wasn’t migrated (fixed), but it does mean that during class loading it already calls the database even if it might not need the controllers (such as a rake task). That can slow it down.
In this particular case the data is cached anyway, so if you would change the DB entries it doesn’t make a difference, but there’s another case where it should be dynamic:
Here we can actually see multiple issues. First of all, it’s marked for translation (N_()
) but with a dynamic string. That can never work and should be N_("Possible values: %s") % Katello::RepositoryTypeManager.generic_content_types.join(", ")
for it to have a chance, but I don’t think we can really make it translatable.
The more interesting part is that it displays the values, but those are loaded on application start up. It doesn’t perform any validation so if the content types change, it’ll still display the old value(s) while accepting the new value(s). You can question the usefulness of the help here.
That it runs on start up can actually trigger interesting failure modes. Bug #37977: Katello prevents foreman server startup when Pulp is not reachable - Katello - Foreman observes that the method call can result in the application reaching out to Pulp and Foreman refuses to start up when Pulp is unavailable.
So we can observe reliability, correctness and performance aren’t what they should be. Question is, what can we do?
I think EnumValidator
today should only be used with true static lists, but perhaps we can enhance it to become dynamic. I opened Support passing a callable to EnumValidator by ekohl · Pull Request #946 · Apipie/apipie-rails · GitHub to do this, but failed to realize it then overlaps with ProcValidator
.
So now I’m opening the topic to a wider audience: what should we do here?