Documentation written by hand is a copy of the implementation, and copies drift — usually within a sprint, and always without anybody noticing.
/**
* @OAGet(
* path="/api/orders/{id}",
* @OAParameter(name="id", in="path", required=true,
* @OASchema(type="integer")),
* @OAResponse(response=200, @OAJsonContent(ref="#/components/schemas/Order"))
* )
*/
public function show(int $id): JsonResponse {}
// vendor/bin/openapi app -o public/openapi.json
The annotations are verbose and are next to the code they describe, which is the entire argument — a route that changes without its annotation changing is a review comment rather than a discovery six months later. Generating from the route table plus the form request classes is the alternative and produces less detail with no annotations at all. Either beats a hand-written document, and the choice is about how much detail the clients need.