# Creating your own strategy
All strategies must implement the ExtractionStrategy
interface (opens new window). It
requires strategies to implement one central handle
method. It receives the resolved route, and the endpoint instance used to collect information about this
route. The job of strategies is analyzing the route, and applying modifications to the endpoint.
This might look like the following:
public function handle(ResolvedRouteInterface $route, Endpoint $endpoint): Endpoint {
if ($route->getHandlerReflector()->getAttributes(Hidden::class)) {
$endpoint->setHidden();
}
return $endpoint;
}
Here, we use reflection to check whether the route handler method has the Hidden
attribute set, and if so, mark the endpoint as hidden accordingly. The
strategy will be invoked for every route found in the application (and matching your inclusion rules), so with
these 7 lines of code we have just added support for hidden routes to our documentation! ...which is already built-in, of course 😉
Strategies don't have to be exhaustive: All of them work on the same endpoint instance, and work together to add pieces of information, one by one.
# Defining the priority
All strategies are required to implement the getPriority
method, which must return an integer priority. Strategies will be sorted by priority, the highest
last, the lowest first. This is the mechanism making sure the Override strategy is run last, unless you choose to overrule it (which we
don't recommend).
For reference, this is the priority map of the built-in strategies:
Strategy | Priority |
---|---|
Override Strategy | 999 |
Attribute Strategy | 120 |
OpenAPI Strategy | 90 |
Return Type Hint Strategy | 60 |
DocBlock Strategy | 30 |
You can fit your strategy in wherever you see fit, but make sure no other strategy overrides your modifications to the endpoints!
# Depending on other strategies
Sometimes, it's essential your strategy is run after another one. For these cases, you can declare dependencies: Herodot will make sure your strategy is invoked after all dependencies have been executed. This is achieved using a dependency graph in the background, which sorts out any chain of complex dependencies, but take care not to form cycles: Herodot will bail out in that case.
public function getDependencies(): ?array
{
return [
AttributeStrategy::class,
MyCustomStrategy::class
];
}
If your strategy does not have any dependencies (which is a good thing), you may simply return null
or an empty array here.
Note that dependencies will interfere with priorities. This is by design and allows shifting priorities as required by your documentation, not by the code. Most of the time, this won't be a problem though.