Repository: knuckleswtf/scribe (php)

Issue:
Body params not working for GET endpoints on v3.
- [x] **I confirm that I have read and attempted the tips in the [Troubleshooting Guide](https://scribe.knuckles.wtf/laravel/troubleshooting).**

**What happened?**
1. I upgraded from v2 to v3 and followed the upgrade guide.
2. Then I ran `php artisan scribe:generate` and everything worked fine.
3. But then I realised that the body params for all my GET requests are gone. POST requests are just fine but for example I have a GET request that requires an `id` parameter in the body and my `@bodyParam id` annotation is no longer being picked up like it was in v2.

Before upgrading (v2):
<img width="592" alt="Screenshot 2021-09-05 at 02 35 17" src="https://user-images.githubusercontent.com/42416996/132112047-96b76579-7101-438e-9873-da423d261dae.png">

After upgrading (v3):
<img width="581" alt="Screenshot 2021-09-05 at 02 33 43" src="https://user-images.githubusercontent.com/42416996/132112017-29704349-944b-4666-9d8f-a70c64ecc3a3.png">

**My environment:**
 - PHP version: 7.4.23
 - Framework: Laravel
 - Laravel/Lumen version: 8.58.0
 - Scribe version: 3.9.1

**My Scribe config (minus the comments):**
```php
return [
    'title' => null,

    'description' => 'Earnie API',

    'routes' => [
        [
            'match' => [
                'domains' => ['*'],
                'prefixes' => ['api/*'],
                'versions' => ['v1'],
            ],
            'include' => [
                // 'users.index', 'healthcheck*'
            ],
            'exclude' => [
                // '/health', 'admin.*'
            ],
            'apply' => [
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Accept' => 'application/json',
                ],

                'response_calls' => [
                    'methods' => [],
                    'config' => [
                        'app.env' => 'documentation',
                        // 'app.debug' => false,
                    ],
                    'queryParams' => [
                        // 'key' => 'value',
                    ],
                    'bodyParams' => [
                        // 'key' => 'value',
                    ],
                    'fileParams' => [
                        // 'key' => 'storage/app/image.png',
                    ],
                    'cookies' => [
                        // 'name' => 'value'
                    ],
                ],
            ],
        ],
    ],

    'type' => 'static',

    'static' => [
        'output_path' => 'public/docs',
    ],
    'laravel' => [
        'add_routes' => true,

        'docs_url' => '/docs',

        /*
         * Middleware to attach to the docs endpoint (if `add_routes` is true).
         */
        'middleware' => [],
    ],

    'auth' => [
        'enabled' => true,

        'default' => true,

        'in' => 'bearer',

        'name' => 'access_token',

        'use_value' => env('SCRIBE_AUTH_KEY'),

        'placeholder' => '{{access_token}}',

        'extra_info' => 'You can retrieve your access token via the `/auth/login` endpoint.',
    ],

    'intro_text' => <<<INTRO
This documentation aims to provide all the information you need to work with our API.

<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
INTRO
    ,

    'example_languages' => [
        'bash',
        'javascript',
        'php'
    ],

    'base_url' => null,

    'postman' => [
        'enabled' => true,

        /*
         * Manually override some generated content in the spec. Dot notation is supported.
         */
        'overrides' => [
            // 'info.version' => '2.0.0',
        ],
    ],

    'openapi' => [
        'enabled' => true,

        'overrides' => [
            // 'info.version' => '2.0.0',
        ],
    ],

    'default_group' => 'Endpoints',

    'logo' => false,

    'faker_seed' => null,

    'strategies' => [
        'metadata' => [
            \Knuckles\Scribe\Extracting\Strategies\Metadata\GetFromDocBlocks::class,
        ],
        'urlParameters' => [
            \Knuckles\Scribe\Extracting\Strategies\UrlParameters\GetFromLaravelAPI::class,
            \Knuckles\Scribe\Extracting\Strategies\UrlParameters\GetFromLumenAPI::class,
            \Knuckles\Scribe\Extracting\Strategies\UrlParameters\GetFromUrlParamTag::class,
        ],
        'queryParameters' => [
            \Knuckles\Scribe\Extracting\Strategies\QueryParameters\GetFromQueryParamTag::class, Strategies\QueryParameters\GetFromFormRequest::class, Strategies\QueryParameters\GetFromInlineValidator::class,
        ],
        'headers' => [
            \Knuckles\Scribe\Extracting\Strategies\Headers\GetFromRouteRules::class,
            \Knuckles\Scribe\Extracting\Strategies\Headers\GetFromHeaderTag::class,
        ],
        'bodyParameters' => [
            \Knuckles\Scribe\Extracting\Strategies\BodyParameters\GetFromFormRequest::class,
            \Knuckles\Scribe\Extracting\Strategies\BodyParameters\GetFromBodyParamTag::class,
            Strategies\BodyParameters\GetFromInlineValidator::class,
        ],
        'responses' => [
            \Knuckles\Scribe\Extracting\Strategies\Responses\UseTransformerTags::class,
            \Knuckles\Scribe\Extracting\Strategies\Responses\UseResponseTag::class,
            \Knuckles\Scribe\Extracting\Strategies\Responses\UseResponseFileTag::class,
            \Knuckles\Scribe\Extracting\Strategies\Responses\UseApiResourceTags::class,
            \Knuckles\Scribe\Extracting\Strategies\Responses\ResponseCalls::class,
        ],
        'responseFields' => [
            \Knuckles\Scribe\Extracting\Strategies\ResponseFields\GetFromResponseFieldTag::class,
        ],
    ],

    'fractal' => [
        'serializer' => null,
    ],

    'routeMatcher' => \Knuckles\Scribe\Matching\RouteMatcher::class,

    'database_connections_to_transact' => [config('database.default')],
    'theme' => 'default',
    'try_it_out' => [
        'enabled' => false,
        'base_url' => null,
    ]
];
```


**Additional info:**
My doc comments above my route handler:
```php
    /**
     * Get Group
     *
     * Retrieves the group specified by `id`.
     *
     * @bodyParam id int required The ID of the group. Example: 1
     *
     * @response 200 {
        "status": "success",
        "message": "string",
        "data": {
            "id": 1,
            "name": "London Group",
            "parent_id": 0,
            "is_default_group": 1,
            "created_at": "2021-01-20 10:08:22",
            "updated_at": "2021-01-20 10:08:22",
            "deleted_at": null,
            "meta": [
                {
                    "name": "title",
                    "content": "Some Metadata Title"
                },
                {
                    "name": "url",
                    "content": "https://www.example.com"
                }
            ]
        }
     }
     */
```

Pull request:
Removed the check that prevented GET endpoint handlers from supportin…
Removed the check that prevented GET endpoint handlers from supporting the `@bodyParams` annotation.

I'm afraid this seems to have caused the following test to fail:
```
1) Knuckles\Scribe\Tests\Unit\ExtractorPluginSystemTest::responses_from_different_strategies_get_added
Illuminate\Contracts\Container\BindingResolutionException: Target class [validator] does not exist.
```

I don't understand the project well enough to fix the test myself although the change has produced the desired result for me in practice.

Closes #316 

Patch:
diff --git a/src/Extracting/Extractor.php b/src/Extracting/Extractor.php
index 32246915..aab23ce7 100644
--- a/src/Extracting/Extractor.php
+++ b/src/Extracting/Extractor.php
@@ -161,9 +161,6 @@ class Extractor
 
     protected function fetchBodyParameters(ExtractedEndpointData $endpointData, array $rulesToApply): void
     {
-        if (in_array('GET', $endpointData->httpMethods)) {
-            return;
-        }
         $this->iterateThroughStrategies('bodyParameters', $endpointData, $rulesToApply, function ($results) use ($endpointData) {
             foreach ($results as $key => $item) {
                 if (empty($item['name'])) {


Test patch:
diff --git a/tests/Unit/ExtractorPluginSystemTest.php b/tests/Unit/ExtractorPluginSystemTest.php
index 3f22aed2..f58d71a2 100644
--- a/tests/Unit/ExtractorPluginSystemTest.php
+++ b/tests/Unit/ExtractorPluginSystemTest.php
@@ -65,6 +65,7 @@ class ExtractorPluginSystemTest extends TestCase
     {
         $config = [
             'strategies' => [
+                'bodyParameters' => [],
                 'responses' => [DummyResponseStrategy200::class, DummyResponseStrategy400::class],
             ],
         ];
@@ -94,6 +95,7 @@ class ExtractorPluginSystemTest extends TestCase
         $config = [
             'strategies' => [
                 'metadata' => [PartialDummyMetadataStrategy1::class, PartialDummyMetadataStrategy2::class],
+                'bodyParameters' => [],
                 'responses' => [],
             ],
         ];
@@ -117,6 +119,7 @@ class ExtractorPluginSystemTest extends TestCase
         $config = [
             'strategies' => [
                 'metadata' => [PartialDummyMetadataStrategy2::class],
+                'bodyParameters' => [],
                 'responses' => [],
             ],
         ];
@@ -140,6 +143,7 @@ class ExtractorPluginSystemTest extends TestCase
         $config = [
             'strategies' => [
                 'metadata' => [NotDummyMetadataStrategy::class, PartialDummyMetadataStrategy1::class],
+                'bodyParameters' => [],
                 'responses' => [],
             ],
         ];