Skip to content

Instantly share code, notes, and snippets.

@renepardon
Created February 15, 2022 09:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renepardon/cdddb32893b7df80b31f489e5f4e8f9c to your computer and use it in GitHub Desktop.
Save renepardon/cdddb32893b7df80b31f489e5f4e8f9c to your computer and use it in GitHub Desktop.
GraphQL Federation - resolve User type through API Gateway
query MyQuery {
# Returns only one result even if using @all on Tenant model
getTenants(filters: {limit: 2}) {
id
name
}
getTenantById(id: "494796f0-4eee-4609-952c-8b1f816dc934") {
name
}
getMe {
firstname
lastname
tenant {
id
name
}
}
getUserById(id: 1) {
id
firstname
lastname
tenant {
id
name
}
}
getUsers {
id
firstname
lastname
tenant {
id
name
}
}
}
extend type Query @guard(with: ["jwt"]) {
getTenantById(id: String! @eq): Tenant
@find(model: "\\App\\Models\\Tenant")
@can(ability: "view")
getTenants(
filters: TenantOptions @spread,
orderBy: [OrderByClause!] @orderBy,
trashed: Trash @trashed
): [Tenant]
@all(model: "\\App\\Models\\Tenant", scopes: ["filters", "tree"])
@can(ability: "viewAny")
}
{
"data": {
"getTenants": [
{
"id": "5078d9fe-df1c-4cf5-b3c4-c761b928a0ee",
"name": "placeat-aut-ab"
}
],
"getTenantById": {
"name": "eum-quod"
},
"getMe": {
"firstname": null,
"lastname": null,
"tenant": {
"id": "494796f0-4eee-4609-952c-8b1f816dc934",
"name": "eum-quod"
}
},
"getUserById": {
"id": "1",
"firstname": "Marianne",
"lastname": "Koss",
"tenant": {
"id": "494796f0-4eee-4609-952c-8b1f816dc934",
"name": "eum-quod"
}
},
"getUsers": [
{
"id": "1",
"firstname": "Marianne",
"lastname": "Koss",
"tenant": {
"id": "494796f0-4eee-4609-952c-8b1f816dc934",
"name": "eum-quod"
}
},
{
"id": "2",
"firstname": "Chyna",
"lastname": "Gusikowski",
"tenant": {
"id": "a873de56-9f23-4e28-9a54-19037392cb3c",
"name": "recusandae-consequuntur"
}
}
]
}
}
type Tenant {
id: String!
name: String!
}
""" Federation specific adjustments """
type User @key(fields: "id") @extends {
id: ID! @external
tenant: Tenant!
# @can(ability: "view")
# TODO somehow we need to pass the current tenant to check against as second argument to the view policy method
}
<?php
namespace App\GraphQL\Entities;
use App\Models\Tenant;
use GraphQL\Client;
use GraphQL\Query;
class User
{
/**
* @param array{__typename: string, id: int} $representation
*
* @return array
*/
public function __invoke(array $representation): array
{
$client = new Client(
'http://localhost:4000/graphql',
[],
[
'connect_timeout' => 5,
'timeout' => 5,
'headers' => [
'Authorization' => request()->header('Authorization'),
'User-Agent' => config('app.name'),
],
]
);
$gql = (new Query('getUserById'))
->setArguments([
'id' => (int)$representation['id'],
])
->setSelectionSet(
[
'id',
'tenant_id',
'firstname',
'lastname',
'email',
'active',
'timezone',
'language',
]
);
$results = $client->runQuery($gql, true);
$user = $results->getData()['getUserById'];
$tenant = Tenant::where('id', $user['tenant_id'])->first();
return array_merge($representation, $user, ['tenant' => $tenant]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment