-1

I am using Lighthouse GraphQL with Laravel 9 for my application. Graphql have standard format and each response show under the data and operation name. It does not show proper response (error/success) to handle for front-end application. Because, on the basis of error code iOS/Android/frontend may work easily. Here is the sample: Request:

query Translations {
        translations {
            name
            slug
        }
    }

Response:

{
        "data": {
            "translations": [
                {
                    "name": "English",
                    "slug": "en_US"
                },
                {
                    "name": "English (United Kingdom)",
                    "slug": "en_UK"
                }      
            ]
        }
    }

I have tried to override response with Laravel response classes and create custom queries/mutations resolver. But, it returns all the information. This should use Graphql "Tailoring your need" also. So, I want to customize the response so that response should include code, status, message, data[].

The result I got:

{
        "status": true,
        "code": 200,
        "message": "",
        "data": [
            {
                "_id": "63b2d767e2a07754b20845f6",
                "name": "English",
                "slug": "en_US",
                "isActive": true,
                "isDefault": true,
                "updated_at": "2023-01-02T13:08:54.940000Z",
                "created_at": "2023-01-02T13:08:54.940000Z",
                "logo": "/United-States.svg"
            },
            {
                "_id": "63b3e78ae2a07754b20845ff",
                "name": "English (United Kingdom)",
                "slug": "en_UK",
                "isActive": true,
                "isDefault": false,
                "updated_at": "2023-01-03T08:30:02.085000Z",
                "created_at": "2023-01-03T08:30:02.085000Z",
                "logo": "/Great-Britain.svg"
            } 
        ]
    }

It should be:

{
        "status": true,
        "code": 200,
        "message": "",
        "data": [
            {     
                "name": "English",
                "slug": "en_US"      
            },
            {      
                "name": "English (United Kingdom)",
                "slug": "en_UK"      
            }    
        ]
    }
RG Servers
  • 1,726
  • 2
  • 11
  • 27
  • Show us how you are executing those queries, show what you have done so far. – RG Servers Jan 31 '23 at 07:25
  • @KGG I have created a Translations custom resolver within that namespace App\GraphQL\Queries; use App\Models\Translation; use App\GraphQL\BaseClass; final class Translations extends BaseClass { public function __invoke($_, array $args) { $translations = Translation::all(); $this->sendResponse($translations, '', $this->HttpCode::$SUCCESS); } } The sendResponse method is defined under BaseClass. The sendResponse method have response format is defined to overwrite dynamically – Niraj Pathak Jan 31 '23 at 07:42

2 Answers2

2

It should be:

{
        "status": true,
        "code": 200,
        "message": "",
        "data": [
            {     
                "name": "English",
                "slug": "en_US"      
            },
            {      
                "name": "English (United Kingdom)",
                "slug": "en_UK"      
            }    
        ]
    }

I would strongly advise against this, as it violates the GraphQL specification:

To ensure future changes to the protocol do not break existing services and clients, the top level response map must not contain any entries other than the three described above.

Use extensions for custom additions. You can add to extensions in Lighthouse by listening to the BuildExtensionsResponse event, see https://lighthouse-php.com/master/api-reference/events.html#buildextensionsresponse

spawnia
  • 879
  • 6
  • 13
1

Lighthouse returns the response based on the GraphQL specification. You have the power to change the response with the EndRequest event. Listen to the event in AppServiceProvider and then manipulate the response in any form that you need.

/**
 * @param Dispatcher $dispatcher
 *
 * @return void
 */
public function boot(Dispatcher $dispatcher): void {
    $dispatcher->listen(
        EndRequest::class,
        function (EndRequest $endRequest) {
            dd($endRequest->response);
        });
}
mostafa
  • 196
  • 4
  • Great. Thanks @mostafa!! It works for me what exactly I want. I need more clarity I can override the response but unable to remove the method/operation name. { "status": true, "code": 200, "message ": "", "data": { "translations": [ { "slug": "en_US", "name": "English" }, { "slug": "en_UK", "name": "English (United Kingdom)" } ] } I want to remove "translations" key and all response should come under data only. How can I track errors as well? – Niraj Pathak Jan 31 '23 at 09:46
  • It is a JSON, convert it to an array and do whatever u want then convert it back to JSON. – mostafa Jan 31 '23 at 10:59
  • Yes. I know and I did the same but I'm unable to send the customized value in the response. It gives original response. $dispatcher->listen( EndRequest::class, function (EndRequest $endRequest) { $data = json_decode($endRequest->response->getContent()); $dataArr = array_values((array)$data->data); $responseData['status']= true; $responseData['code'] = 200; $responseData['data'] = $dataArr[0]; return json_encode($responseData); }); – Niraj Pathak Jan 31 '23 at 11:58
  • Please check the current code. Am I doing wrong. According to Request lifecycle where should response go. – Niraj Pathak Jan 31 '23 at 11:59
  • $endRequest->response->setContent(json_encode($responseData)); – mostafa Jan 31 '23 at 12:58