Skip to content

Conversation

nicodevs
Copy link
Contributor

@nicodevs nicodevs commented Dec 29, 2024

This PR introduces a new configuration option, generate_resource_collection_classes, to toggle the generation of resource collection classes in Blueprint.

Current behaviour

To return a resource collection, Blueprint creates a resource collection class. These classes allows adding custom metadata that may need to be returned with the collection.

class PostCollection extends ResourceCollection
{
    public function toArray(Request $request): array
    {
        return [
            'data' => $this->collection,
        ];
    }
}

Blueprint uses them in controllers using the resource statement, generating code like this:

use App\Http\Resources\PostCollection;
use App\Http\Resources\PostResource;

public function index(Request $request): PostCollection
{
    $posts = Post::paginate();

    return new PostCollection($posts);
}

public function store(PostStoreRequest $request): PostResource { ... }

However, as convenient as these dedicated classes are for extending basic functionality, they are not necessary when dealing with simple collections, as all resources provide a collection method to generate an "ad-hoc" resource collection on the fly.

So given a PostResource, the controller can do:

-use App\Http\Resources\PostCollection;
use App\Http\Resources\PostResource;

-public function index(Request $request): PostCollection
+public function index(Request $request): ResourceCollection
{
    $posts = Post::paginate();

-    return new PostCollection($posts);
+    return PostResource::collection($posts);
}

public function store(PostStoreRequest $request): PostResource { ... }

Proposed Feature

A new configuration option, generate_resource_collection_classes, toggles the generation of resource collection classes in Blueprint.

This feature is useful for developers who prefer a leaner approach to resource handling by relying solely on resource classes and their collection methods, reducing the number of generated files.

'generate_resource_collection_classes' => true,
  • If this option is true, it will generate resource collection classes (e.g., PostResourceCollection). This is the default value, maintaining existing behavior where dedicated resource collection classes are generated. It also defaults to true if the value is missing from the config (useful for people who already published the configuration file).

  • If this option is false, it will only generate resource classes (e.g., PostResource) and use their collection method instead.

Testing

Added test cases to verify:

  • Resource collection classes are generated when the option is enabled.
  • Resource collection classes are not generated when the option is disabled.
  • Controllers return the correct class type.

Please let me know if this approach is valid. I would love to see this feature available, happy to make a PR to the docs repo if it does. Thank you!

@nicodevs nicodevs force-pushed the generate-resource-collections branch from 9d5bf49 to a567763 Compare December 29, 2024 23:08
@nicodevs nicodevs marked this pull request as ready for review December 30, 2024 01:41
@jasonmccreary
Copy link
Collaborator

Thanks for the feature.

Can we add a test to make sure if a controller returns a resource and a resource collection when this option is true that Blueprint generates the correct code (a single resource class with both methods).

@nicodevs
Copy link
Contributor Author

nicodevs commented Dec 30, 2024

Thank you for considering it!


When it's true, I believe that is covered in the test output_generates_controllers_for_tree, using the following data from line 275:

['drafts/api-resource-pagination.yaml', 'app/Http/Controllers/PostController.php', 'controllers/api-resource-pagination.php'],

The test checks that the default code is correctly generated: api-resource-pagination.php

When it is false, I added the test output_generates_controller_without_generating_resource_collection_classes. This is the generated code that we are asserting against: without-generating-resource-collection-classes.php


Additionally, in terms of testing the ResourceGenerator, the existing tests cover the default true value: output_writes_resources_for_render_statements, output_writes_namespaced_classes, output_writes_nested_resource, and output_api_resource_pagination.

When it is false, I have added the tests output_writes_resource_for_resource_statements_without_generating_resource_collection_classes, output_writes_nested_resource_without_generating_resource_collection_classes, and output_api_resource_pagination_without_generating_resource_collection_classes.

Let me know if that covers it, happy to add more tests if needed. Thank you!

@jasonmccreary jasonmccreary merged commit 6e9221b into laravel-shift:master Dec 30, 2024
25 checks passed
@nicodevs nicodevs deleted the generate-resource-collections branch January 5, 2025 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants