Responses
Scramble generates documentation for endpoint responses by analyzing the source code of the controller’s method. It examines the inferred return type, calls to various methods (e.g., validate
or authorize
), and other statements to identify the different types of responses that an endpoint may produce.
Currently, these types will be automatically documented as responses:
- API resources (instances of classes extending
JsonResource
) - Collections of API resources (both anonymous collections and dedicated classes)
- Some
response()
(ResponseFactory
) support:response()->make(...)
,response()->json(...)
,response()->noContent()
JsonResponse
andResponse
instances- Models
- Simple types: arrays, strings, numbers, etc.
Paginated responses are also supported, but they need to be documented in PHPDoc for now.
On type inference
Scramble uses type inference based on source code analysis to automatically determine the types of variables and expressions. This means that Scramble can understand what type of data (e.g., strings, numbers, objects) each part of the code is working with, even if the code does not explicitly declare it.
With this technique, Scramble can figure out the likely data types that a controller’s method will return without needing extra explanations. It looks at how the method processes data, the methods it uses, and other hints to infer the possible return types.
This process allows Scramble to generate comprehensive and accurate documentation for the API. It also reduces the need to manually document the responses, making the documentation process more efficient and less error-prone.
Types priority
Scramble extracts controller’s method return type based on the following priority:
- PHPDoc comment (
@response
tag) - gives ability to document arbitrary response types - Typehint - if the method has a typehint and doesn’t have a PHPDoc comment, the typehint will be used
- Code return statements - if the method doesn’t have a PHPDoc
@response
tag, and inferred return type is more specific than typehint, the inferred type will be used
This is implemented in this way so if needed, you can override the inferred type with a typehint or PHPDoc comment.
Manual hinting in PHPDoc
Also, the response can be documented in PHPDoc using @response
tag. This is useful when you notice that the inferred type is not correct or you want to document a custom response type.
Read more about the proper PHPDoc type syntax in PhpStan docs.
API resources
Model resolution
All resource property types that are accessed on $this
or $this->resource
will be resolved from the corresponding model attributes.
By default, Scramble tries to find a model in App\Models
namespace, based on resource name. Before the lookup resource name is converted to singular form (TodoItemsResource
→ TodoItem
).
You can provide the name of the model manually in case you have your custom models namespaces by adding PHPDoc to the resource class. You can either document $resource
property type, or define the model as a @mixin
:
And @mixin
example:
If model for resource is not found, all the fields will have string
type in docs.
Automatically supported fields types
- Model attribute type (
$this->id
,$this->resource->id
)
- Nested API resources
- Conditional merging of nested API resources
- Arrays
- Conditional merging of the arrays in the response:
merge
mergeWhen
when
All the conditional fields will be marked as optional in resulting docs.
Also, API resources are stored in OpenAPI docs as reference and usage of the resources across other resources will be rendered as using schema reference in docs.
Manually describing the fields
For the cases when automatic field type resolution is not working, or you need to add a description to the field, you can add PHPDoc comment:
You can use other resource classes or more complex types to document more complex structures:
This is the format of type annotations used by PhpStan. You can read more about it here: https://phpstan.org/writing-php-code/phpdoc-types.
API resources collection
This sort of response can be automatically analyzed from code return statement.
If you need some code manipulation on the object and it cannot be automatically inferred, you can add the type manually.
To manually add this response type you add this to your PHPDoc like this:
Additional collection’s data
Scramble will automatically document additional data that is added to the collection using additional
method.
Models
When you don’t have a resource and simply return a model from controller’s method, Scramble will be able to document that as well.
When documenting models, Scramble will document what the model’s toArray
returns. So if toArray
is overridden, it should return an array to be properly analyzed.
Please note that if you don’t type annotate a method’s return type, the model type should be specified in arguments list. Otherwise, Scramble won’t be able to infer the returned variable type and document it properly. Also, now only relations that are always present on a model ($with
property) are documented.
Paginated responses
Paginated response cannot be inferred from code automatically for now, so you need to typehint it manually in PHPDoc.
For example, here is a paginated anonymous resource collection:
In case the paginated response is not wrapped as a collection, you can annotate it like so:
This will add all the meta and other information to the resulting docs.
Scramble supports all available paginator classes:
Illuminate\Pagination\LengthAwarePaginator
(returned when you callpaginate
method on a query builder),Illuminate\Pagination\Paginator
(returned when you callsimplePaginate
method on a query builder),Illuminate\Pagination\CursorPaginator
(returned when you callcursorPaginate
method on a query builder).
Error responses
By analyzing the codebase Scramble can not only understand OK responses, but error responses as well. Here are the cases which Scramble understand and can document.
Call to validate
and authorize
in controller
Calls to validate
and authorize
will be documented as corresponding error responses in resulting docs: responses with 422
and 403
statuses respectively.
Model binding in route
When model binding is used, Scramble adds possible 404
error response to the documentation. This is the case when a model is not found.
Abort helpers
When using abort helpers (abort
, abort_if
, abort_unless
), Scramble will document the resulting response.
Currently only numeric code
is supported. Message content (message
) will be documented as an example in resulting docs.
For example, this line of code:
Corresponds to the error response in documentation with code 400
and message
property with an example (This case is not supported
).
Exceptions
Under the hood Scramble understands that abort*
helpers, *::validate
, *::authorize
methods throw exceptions. Then, these exceptions are documented as error responses.
This means that if you add @throws
annotation with a supported exception to your route’s controller method, Scramble will pick it up and document it as the error response.
Here are the exceptions that will be automatically documented by Scramble as a response. All the exceptions that extend the following exceptions classes will also be documented as the same responses.
Exception | Status code |
---|---|
Illuminate\Auth\AuthenticationException | 401 |
Illuminate\Auth\Access\AuthorizationException | 403 |
Symfony\Component\HttpKernel\Exception\HttpException | $statusCode property value |
Illuminate\Database\RecordsNotFoundException | 404 |
Symfony\Component\HttpKernel\Exception\NotFoundHttpException | 404 |
Illuminate\Validation\ValidationException | 422 |
Any instance of Symfony\Component\HttpKernel\Exception\NotFoundHttpException
will be documented as the error response with the status code in $statusCode
property. But it is important to keep in mind, that the status code type must be literal integer so Scramble is able to “get” the value:
In case you have custom exception, you can define how the exception is represented as a response using ExceptionToResponseExtension
.
Here are some examples of this kind of extensions that add support for already mentioned exceptions:
Response description
Description can be added to the response by adding a comment right before the return
in a controller.
Response status and type can be added manually as well using @status
and @body
tags in PHPDoc block before the return
.