folkloreinc / laravel-graphql Goto Github PK
View Code? Open in Web Editor NEWFacebook GraphQL for Laravel 5. It supports Relay, eloquent models, validation and GraphiQL.
Facebook GraphQL for Laravel 5. It supports Relay, eloquent models, validation and GraphiQL.
When asking GraphQL to build the schema of a type, custom field using Type::listof(. . .)
return a null type
Request :
{
__type(name: "User") {
name
fields {
name
type {
name
}
}
}
}
Reponse :
{
"data":{
"__type":{
"name": "User",
"fields":[
{"name": "followings", "type":{"name": null }},
]
}
}
}
Does this project support operationName for mutations?
GraphQL-PHP seems to support it
https://github.com/webonyx/graphql-php#http-endpoint
Is using fragments available ??
Any example of doing that ?
I'm trying to install this package on top of a Laravel 5.3 project, but it seems to depend on illuminate/support 5.2.*
. Would it be possible to support the latest Laravel version?
Thanks for reading ๐
Hi there,
does anybody else have the problem that cyclic type relationships lead to an empty white page when quering?
e.g. in my case I have a comment type. one comment can have sub-comments and so on... unfortunately it is not possible to define these type relationship.
Example code:
class CommentType extends GraphQLType {
protected $attributes = [
'name' => 'Comment',
'description' => 'a comment to a wall entry'
];
public function fields()
{
return [
'id' => [
'type' => Type::nonNull(Type::int()),
'description' => 'The id of the comment'
],
'text' => [
'type' => Type::nonNull(Type::string()),
'description' => 'the content of the comment'
],
'author' => [
'type' => Type::nonNull(GraphQL::type("user")),
'description' => 'The id of the wall entry'
],
'parent' => [
'type' => GraphQL::type("comment"),
'description' => 'parent comment'
],
'comments' => [
'type' => Type::listOf(GraphQL::type("comment")),
'description' => 'comments on this comment'
]
];
}
/**
* @param Comment $model
* @param array $args
* @return Comment[] mixed
*/
protected function resolveCommentsField($model, $args){
return $model->children;
} ...
in my comment model i defined the relation as follows:
public function children(){
return $this->hasMany(self::class,"fk_comment_id","id");
}
as i mentioned before, quering this type does lead to an empty white page. I remove the cyclic relations (parent and comments) it works just fine.
Am I doing something wrong or is it an graph-ql implementation problem?
Leonhard
Is there currently a way to get the arguments of a relationship in the resolve function? With the following (using the instructions in the README) I can determine if I need to eager load a relationship in the parent's resolve:
class CustomersQuery extends Query
{
//...
public function resolve($root, $args, ResolveInfo $info)
{
$customers = Customer::query();
$fields = $info->getFieldSelection(3);
foreach ($fields as $field => $keys) {
if ($field == 'orders') {
// Can I get the arguments for orders here so I can put
// a constraint on the relationship? For Example:
// $customers->with(['orders' => function ($q) use ($args) {
// $q->take($args['orders.limit']);
// }]);
$customers->with('orders');
}
}
return $customers->take($args['limit'])->get();
}
}
And with my type definition I can add arguments and grab them in the field's resolve function:
class CustomerType extends GraphQLType
{
public function fields()
{
$orderType = new OrderType;
return [
// ...
'orders' => [
'type' => Type::listOf($orderType->toType()),
'description' => 'Customer orders.',
'args' => [
'limit' => [
'name' => 'limit',
'type' => Type::nonNull(Type::int())
]
],
'resolve' => function ($customer, $args) {
return $customer->orders()->take($args['limit'])->get();
}
]
];
}
}
However, at that point I've already pull all related records from the DB. Is there a way to get the arguments in the parent's resolve function?
Btw, this package has made working with GraphQL an absolute joy!
I would be very pleased if you could add an example about how to create mutations with laravel-graphql as well as how to create input (object) types.
Thanks :)
I do the request as in the readme /graphql?query=query+FetchUsers{users{id,email}}
, but i got error
{
"data": null,
"errors": [
{
"message": "Syntax Error GraphQL request (1:1) Unexpected EOF\n\n1: \n ^\n",
"locations": [
{
"line": 1,
"column": 1
}
]
}
]
}
this is my query class
<?php
namespace App\Http\GraphQL\Query;
use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Query;
use App\User;
class UsersQuery extends Query {
protected $attributes = [
'name' => 'Users query'
];
public function type()
{
return Type::listOf(GraphQL::type('user'));
}
public function args()
{
return [
'id' => ['name' => 'id', 'type' => Type::string()],
'email' => ['name' => 'email', 'type' => Type::string()]
];
}
public function resolve($root, $args)
{
if(isset($args['id']))
{
return User::where('id' , $args['id'])->get();
}
else if(isset($args['email']))
{
return User::where('email', $args['email'])->get();
}
else
{
return User::all();
}
}
}
this is my type class
<?php
namespace App\Http\GraphQL\Type;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as GraphQLType;
class UserType extends GraphQLType {
protected $attributes = [
'name' => 'User',
'description' => 'A user'
];
public function fields()
{
return [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the user'
],
'email' => [
'type' => Type::string(),
'description' => 'The email of user'
]
];
}
// If you want to resolve the field yourself, you can declare a method
// with the following format resolve[FIELD_NAME]Field()
protected function resolveEmailField($root, $args)
{
return strtolower($root->email);
}
}
and this is my config
<?php
return [
// The prefix for routes
'prefix' => 'graphql',
// The routes to make GraphQL request. Either a string that will apply
// to both query and mutation or an array containing the key 'query' and/or
// 'mutation' with the according Route
//
// Example:
//
// 'routes' => [
// 'query' => '/query',
// 'mutation' => '/mutation'
// ]
//
'routes' => '/',
// The controller to use in GraphQL request. Either a string that will apply
// to both query and mutation or an array containing the key 'query' and/or
// 'mutation' with the according Controller and method
//
// Example:
//
// 'controllers' => [
// 'query' => '\Folklore\GraphQL\GraphQLController@query',
// 'mutation' => '\Folklore\GraphQL\GraphQLController@mutation'
// ]
//
'controllers' => '\Folklore\GraphQL\GraphQLController@query',
// Any middleware for the graphql route group
'middleware' => ['oauth:public', 'cors'],
// The schema for query and/or mutation. It expects an array to provide
// both the 'query' fields and the 'mutation' fields. You can also
// provide directly an object GraphQL\Schema
//
// Example:
//
// 'schema' => new Schema($queryType, $mutationType)
//
// or
//
// 'schema' => [
// 'query' => [
// 'users' => 'App\GraphQL\Query\UsersQuery'
// ],
// 'mutation' => [
//
// ]
// ]
//
'schema' => [
'query' => [
'users' => 'App\Http\GraphQL\Query\UsersQuery',
],
'mutation' => [
],
],
// The types available in the application. You can then access it from the
// facade like this: GraphQL::type('user')
//
// Example:
//
// 'types' => [
// 'user' => 'App\GraphQL\Type\UserType'
// ]
//
'types' => [
'users' => 'App\Http\GraphQL\Type\UserType',
],
// This method will be passed the Error object for each errors GraphQL catch.
// The method should return an array representing the error.
// Typically ['message' => '','locations' => []].
'error_formatter' => ['\Folklore\GraphQL\GraphQL', 'formatError']
];
Hi, first of all thanks for the great package.
What do you think about adding config options for the QueryComplexity and QueryDept rules of graphql-php ? I know I can set them in my bootstrap for example :
$queryComplexity = DocumentValidator::getRule('QueryComplexity');
$queryComplexity->setMaxQueryComplexity($maxQueryComplexity = 1);
$queryDepth = DocumentValidator::getRule('QueryDepth');
$queryDepth->setMaxQueryDepth($maxQueryDepth = 1);
But I think adding options in config/graphql.php would be more user friendly. What do you think ? If you think it's a good idea I could send a PR.
Thanks.
I'm using a graphql mutation to change a users email adress. Therefore I use the rule() method in my mutation but I need to pass the user id to the "unique" validation rule so that it ignores the user on updating.
How can I achieve this or is this not supported?
https://unpkg.com/[email protected]/graphiql.min.js
Not found: file "/graphiql.min.js" in package [email protected]
v0.8.0 works: https://unpkg.com/[email protected]/graphiql.min.js
Should look into some way of getting a stable source for those files! (maybe ship with a specific graphiql version?)
Hi,
I'm trying to access Eloquents withCount to get the count of a relation as a property which works fine when it's in the first level of the query, but in the second level it always returns null.
Can you help me why this happens?
For example:
query clubs(slug:"adagio"){
id,
name,
likes_count, // returns the count of the likes
events {
likes_count, // returns null
name
}
}
Thanks
Hey guys, does this package also work in lumen?
I think it would make sense there, because lumen seems to be just for api stuff like this and should be faster than laravel by default.
What do you say?
I think there is a problem with the way $args is fetched in the resolve function. When i set the variable like this:
query getNews($offset: Int = 0, $limit: Int = 3) {
news(offset: $offset, limit: $limit) {
id,
headline,
article,
total_news_count,
date,
slug,
author {
username
}
}
}
I get the correct response. 3 articles with the correct offset. But when i do it this way:
query getNews($offset: Int, $limit: Int) {
news(offset: $offset, limit: $limit) {
id,
headline,
article,
total_news_count,
date,
slug,
author {
username
}
}
}
and set the variables with Angular2 the server doesn't set the appropriate $args columns. The variables are sent to the server
Here is my NewsQuery
<?php
namespace App\GraphQL\Query;
use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Query;
use App\News;
class NewsQuery extends Query {
protected $attributes = [
'name' => 'news'
];
public function type()
{
return Type::listOf(GraphQL::type('newsArticle'));
}
public function args()
{
return [
'id' => [
'type' => Type::int()
],
'headline' => [
'type' => Type::string()
],
'slug' => [
'type' => Type::string()
],
'article' => [
'type' => Type::string()
],
'user_id' => [
'type' => Type::int()
],
'author' => [
'type' => Type::listOf(GraphQL::type('user')),
],
'offset' => [
'type' => Type::int(),
'defaultValue' => 0
],
'limit' => [
'type' => Type::int(),
'defaultValue' => 3
],
'total_news_count' => [
'type' => Type::int()
],
'date' => [
'type' => Type::string()
]
];
}
public function resolve($root, $args)
{
if(isset($args['id']))
{
return News::where('id', $args['id'])->get();
}
else if(isset($args['slug']))
{
return News::where('slug', $args['slug'])->get();
}
else if(isset($args['offset']))
{
return News::skip($args['offset'])->take($args['limit'])->orderBy('id', 'DESC')->get();
}
}
}
Here is my Angular2 component
import { Component, OnInit } from '@angular/core';
import {Angular2Apollo} from 'angular2-apollo';
import {Subscription} from 'rxjs/Subscription';
import { ApolloQueryObservable } from 'angular2-apollo';
import {NewsArticle} from '../classes/NewsArticle';
import {NewsQuery} from './news.model';
@Component({
selector: 'news',
templateUrl: './news.component.html'
})
export class NewsComponent implements OnInit {
public buttonDisabled:boolean = false;
public loading:boolean = true;
private currentID:number = null;
newsObs: ApolloQueryObservable<any>;
newsSub: Subscription;
newsArticles: NewsArticle[] = [];
itemsPerPage:number = 3;
constructor(private apollo: Angular2Apollo) { }
ngOnInit() {
this.newsObs = this.apollo.watchQuery({
query: NewsQuery,
variables: {
offset: 0,
limit: this.itemsPerPage
},
forceFetch: true,
});
this.newsSub = this.newsObs.subscribe(({data, loading}) => {
this.newsArticles = data.news;
this.loading = loading;
});
}
fetchMore() {
this.newsObs.fetchMore({
variables: {
offset: this.newsArticles.length,
},
updateQuery: (prev, { fetchMoreResult }) => {
if (!fetchMoreResult.data)
return prev;
var t = Object.assign({}, prev, {
newsArticles: [...prev.news, ...fetchMoreResult.data.news],
});
},
});
}
}
I'm following the readme to setup my first graphql API, but I come across some issues.
according to https://github.com/Folkloreatelier/laravel-graphql#creating-a-query , this should return a response when invoking http://homestead.app/graphql?query=query+FetchUsers{users{id,email}}
but I my lumen 5.3.2 project it just returned a 404 not found.
noticing that in routes.php#L64 there is no router for get requests, So I suggest whether change the readme file that use a post request, like:
curl 'http://homestead.app/graphql/' --data 'query=query+FetchUsers{users{id,email}}'
or add
$router->get(preg_replace($schemaParameterPattern, '', $queryRoute), array(
'as' => 'graphql.query',
'uses' => $queryController
));
in routes.php
Like @chrissm79, I am too trying to implement the Relay specifications set out for a GraphQL server. The Relay Global Object Identification Specification states the following:
The server must provide an interface called Node. That interface must include exactly one field, called id that returns a nonโnull ID.
This id should be a globally unique identifier for this object, and given just this id, the server should be able to refetch the object.
Here is my attempt to implement it:
NodeInterface.php
<?php namespace App\GraphQL\Types;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as GraphQLType;
class NodeInterface extends GraphQLType
{
protected $attributes = [
'name' => 'Node',
'description' => 'Node Interface'
];
public function fields()
{
return [
'id' => [
'type' => Type::nonNull(Type::id()),
'description' => 'Id of the node'
]
];
}
}
graphql.php
...
'schema' => [
'query' => [
'node' => App\GraphQL\Queries\NodeQuery::class,
'users' => App\GraphQL\Queries\UsersQuery::class,
],
],
...
'types' => [
'node' => App\GraphQL\Types\NodeInterface::class,
'user' => App\GraphQL\Types\UserType::class
]
...
NodeQuery.php
This, I suppose, is the place where the base64 encoded global id gets decoded into i.e. id+type information in your Laravel app using a helper function like decodeGlobalIdField($args['globalId'])
. How can I access the globalId
if I need it outside of the resolve()
function? Do I need it outside of it? What do I return in the type()
function?
<?php namespace App\GraphQL\Queries;
use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Query;
class NodeQuery extends Query {
protected $attributes = [
'name' => 'node'
];
public function type()
{
return GraphQL::type('node');
}
public function args()
{
return [
];
}
public function resolve($root, $args)
{
}
}
Any hints and tips are helpful!
At the end of the day I try to rebuild the following introspection query:
{
__type(name: "Node") {
name
kind
fields {
name
type {
kind
ofType {
name
kind
}
}
}
}
}
... that shall lead to the following output:
{
"__type": {
"name": "Node",
"kind": "INTERFACE",
"fields": [
{
"name": "id",
"type": {
"kind": "NON_NULL",
"ofType": {
"name": "ID",
"kind": "SCALAR"
}
}
}
]
}
}
So far, I am making the following introspection query:
{
__type(name: "Node"){
name
description
kind
}
}
... for which I am yielding
{
"data": {
"__type": {
"name": "Node",
"description": "Node Interface",
"kind": "OBJECT"
}
}
}
If I'd had to cut my question short, what do I have to do for "kind" to return "INTERFACE" instead of "OBJECT"?
Hi, I've encountered an issue that results in an infinite loop and a segmentation fault with trying to use lists to definite simple relationships versus a Relay connection. Is there something I'm doing incorrectly for this situation or is this an issue? I could use a connection though in this use case there at most are 1-2 related objects so a connection is overkill and a list would be more appropriate.
I have a SessionType which has a list of payments for the one-to-many relationship. In relayFields() I'm returning this for payments:
'payments' => [
'type' => Type::listOf(GraphQL::type('payment')),
'description' => 'Payments for session',
'resolve' => function (Session $session) {
return $session->payments;
}
],
In my PaymentType I then have the inverse:
'session' => [
'type' => GraphQL::type('session'),
'description' => 'Session that payment is connected to',
'resolve' => function (Payment $payment) {
return $payment->session;
}
],
This results in an infinite loop since it is trying to create the PaymentType while trying to create the SessionType which then repeats the process resulting in a loop
Used the type and query example shown and this query works fine
http://homestead.app/graphql?query=query+FetchUsers{users{id,email}}
However when I try the example to use variables in the query using this query
http://homestead.app/graphql?query=query+FetchUserByID($id:String){user(id:$id){id,email}}¶ms={"id":"1"}
I get this error:
{"data":null,"errors":[{"message":"Cannot query field user on Query","locations":[{"line":1,"column":33}]},{"message":"Variable \"$id\" is never used.","locations":[{"line":1,"column":21}]}]}
I am getting the following error
Class 'GraphQL' not found in /Users/jakedavies/dev/Zeus/app/GraphQL/Query/AdsQuery.php on line 19
Using the following query class, set up the same way as the example is.
<?php
namespace App\GraphQL\Query;
use Folklore\GraphQL\Support\Query;
use GraphQL;
use GraphQL\Type\Definition\Type;
use App\Ad;
class AdsQuery extends Query {
protected $attributes = [
'name' => 'Ads query'
];
public function type()
{
return Type::listOf(GraphQL::type('ad'));
}
public function args()
{
return [
'id' => ['name' => 'id', 'type' => Type::string()],
'name' => ['name' => 'name', 'type' => Type::string()]
];
}
public function resolve($root, $args)
{
if(isset($args['id']))
{
return Ad::find($args['id']);
}
else
{
return Ad::all();
}
}
}
Where is GraphQL loaded?
In the example given if i add a argument like
query FetchUsers
{
users(id : "1")
{
email
}
}
I'm getting error
Exception in Utils.php line 155:
User Error: expected iterable, but did not find one.
in Utils.php line 155
at Utils::invariant(false, 'User Error: expected iterable, but did not find one.') in Executor.php line 562
at Executor::completeValue(object(ExecutionContext), object(ListOfType), object(ArrayObject),
object(ResolveInfo), object(User)) in Executor.php line 497
at Executor::completeValueCatchingError(object(ExecutionContext), object(ListOfType), object(ArrayObject), object(ResolveInfo), object(User)) in Executor.php line 474
at Executor::resolveField(object(ExecutionContext), object(ObjectType), array(null), object(ArrayObject), 'users', array()) in Executor.php line 205
at Executor::executeFieldsSerially(object(ExecutionContext), object(ObjectType), array(null), object(ArrayObject)) in Executor.php line 224
at Executor::executeFields(object(ExecutionContext), object(ObjectType), array(null), object(ArrayObject)) in Executor.php line 152
at Executor::executeOperation(object(ExecutionContext), object(OperationDefinition), null) in Executor.php line 94
at Executor::execute(object(Schema), object(Document), null, null, null) in GraphQL.php line 29
at GraphQL::execute(object(Schema), 'query Fs{users(id : "1"){id ,email}}', null, null) in GraphQL.php line 78
at GraphQL->query('query Fs{users(id : "1"){id ,email}}', null) in routes.php line 39
at GraphQLServiceProvider->{closure}(object(Request))
If i query without argument it is working fine!
I don't know how to create a pull request, to change the Readme.MD file.
I found how to use the variables feature documented.
It would be useful to add how to use parameters in the queries.
Example:
query myQuery($size:Int,$array:[String]){
query(fields:$array){
picture(size:$size),
name
}
}
and along with the query, there should be a params
query field JSON-encoded
www.[...]/graphql?query=[...]¶ms={size:10,array:["id1","id2","id3"]}
and the $args
parameter in the resolve
function will be filled accordingly.
I would do it, but I have no idea of how pull requests work. I'm a GitHub n00b, sorry.
Could you please provide an working example app?
Thanks
Andreas
Hey, It's Awesome Package~ ๐ ๐
But I just wondering why I got error when trying to publish the configuration of graphql package in my Lumen. The error look like this:
$ php artisan graphql:publish
PHP Fatal error: Call to undefined method Folklore\GraphQL\LumenServiceProvider::command() in /var/www/proyek/goodmovie/vendor/folklore/graphql/src/Folklore/GraphQL/LumenServiceProvider.php on line 50
[Symfony\Component\Debug\Exception\FatalErrorException]
Call to undefined method Folklore\GraphQL\LumenServiceProvider::command()
Did I make any mistake?
I have noticed that the current implementation has bit of an ambiguity when it comes to the names of Queries(maybe types also). Let me illustrate that.
In my config I have:
'schema' => [
'query' => [
'usersQuery1' => 'App\GraphQL\Query\UsersQuery',
],
],
So when I query I need to use the name of the query like this.
query test {
usersQuery1 {
name
}
}
However I still have the option to specify the query name inside the Query itself:
namespace App\GraphQL\Query;
class UsersQuery extends Query {
protected $attributes = [
// this name is returned for introspection queries
'name' => 'usersQuery2',
'description' => 'Query to fetch the user type',
];
...
}
So which one of the names is actually used? I was using the GraphiQL and it becomes obvious quickly that both are. I can only use usersQuery1
to query the data. But when I issue an introspection query (or open the docs in in GraphiQL) I get usersQuery2
. This also breaks autocompletion in GraphiQL.
Is this something that anyone else noticed or has had issues with? Do you think it is worth fixing? As a workaround I am using the same name in the config and the query but I think it is bad practice and error prone to have the same name in two places. My suggestion would be to use the name of the Query if it is given and only use the key that is used in the config otherwise. What do you think of that?
When resolving a query is it possible to get the list of types requests in order to eager load Eloquent relationships?
Hi there,
Forgive me if this is dead obvious. When I delete a row and then try to return it in a mutation, I get the error "Cannot return null for non-nullable type", presumably because something on the backend is querying a now deleted row. I can work around this by setting a type property return value to nullable, but then I get a null return values.
I want to return the object that I'm deleting. Or, at least return the id. Is this possible?
something like
mutation deleteThing(thing_id: 2){ thing_id}
or even just
mutation deleteThing(thing_id: 2){ message }
Ideas for doing this?
Thank you! (and I suppose this is more a request for documentation than anything)
If i use a class path to custom field i get
"message": "Undefined index: type",
"status_code": 500,
"debug": {
"line": 110,
"file": "/var/www/laravel/plugins/robocode/api/vendor/webonyx/graphql-php/src/Type/Definition/FieldDefinition.php",
This package looks really promising @dmongeau, I'd love to use it in production but the lack of tests scares me. Is it on the road map to add tests to the package?
I have a very generic question: How would you deal with protected queries? I don't really see a good way to implement it in any way? Is it possible that someone gives me an hint or an example?
(I'm using tymondesigns/jwt-auth for token based authentication in Laravel)
Is it possible to do union types? I can't get them too work. eg:
https://github.com/webonyx/graphql-php/blob/master/docs/type-system/unions.md
// inside Query
public function args()
{
$stringOrStringArray = new \GraphQL\Type\Definition\UnionType([
'name' => 'StringOrStringArray',
'types' => [
Type::string(),
Type::listOf(Type::string()),
],
'resolveType' => function($value) {
if (is_array($value)) {
return Type::listOf(Type::string());
} else {
return Type::string();
}
}
]);
return [
'id' => ['type' => Type::ID()],
'model' => ['type' => $stringOrStringArray],
'model_id' => ['type' => Type::ID()],
'take' => ['type' => Type::int()],
'page' => ['type' => Type::int()],
];
}
When I attempt to submit a mutation, I am getting the following output:
{
"data": null,
"errors": [
{
"message": "Syntax Error GraphQL request (14:10) Expected Name, found {\n\n13: # will appear in the pane to the right.\n14: mutation {\n ^\n15: CreateUser (\n",
"locations": [
{
"line": 14,
"column": 10
}
]
}
]
}
# I initially attempted to use the name createUser (lowercase 'c'), but GraphiQL was giving me
# an error that it couldn't query the field 'createUser' on Mutation and I still got the same
# error message as above
mutation {
CreateUser (
firstName: "John"
lastName: "Doe"
email: "[email protected]"
password: "secret"
) {
firstName
lastName
email
}
}
namespace App\Http\GraphQL\Mutations;
use GraphQL;
use Hash;
use App\Models\User;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Mutation;
class CreateUserMutation extends Mutation
{
/**
* Attributes of mutation.
*
* @var array
*/
protected $attributes = [
'name' => 'CreateUser'
];
/**
* Type that will be mutated.
*
* @return mixed
*/
public function type()
{
return GraphQL::type('user');
}
/**
* Arguments of mutation.
*
* @return array
*/
public function args()
{
return [
'firstName' => [
'name' => 'firstName',
'type' => Type::nonNull(Type::string())
],
'lastName' => [
'name' => 'lastName',
'type' => Type::nonNull(Type::string())
],
'email' => [
'name' => 'email',
'type' => Type::nonNull(Type::string())
],
'password' => [
'name' => 'password',
'type' => Type::nonNull(Type::string())
]
];
}
/**
* Resolve mutation.
*
* @param string $root
* @param array $args
* @return User
*/
public function resolve($root, $args)
{
$user = new User($args);
$user->password = Hash::make($args['password']);
$user->save();
return $user;
}
}
'schema' => [
'query' => [
'user' => App\Http\GraphQL\Queries\UserQuery::class,
// ...
],
'mutation' => [
'createUser' => App\Http\GraphQL\Mutations\CreateUserMutation::class,
]
],
'types' => [
'user' => App\Http\GraphQL\Types\UserType::class,
// ...
]
]
thanks for such a great package, however im a bit stuck for how to authorize access to specific fields from a model.
consider you have a model "reservations" which has the fields "table", "time", "person".
if i query a reservation and I AM NOT the owner of the reservation, or an admin i should only be able to return "table" and "time", even if the query requests "person".
how would you consider handling this?
I quickly browsed through the code and didn't seem to find anything that wouldn't work on 4.2.
Is the 5.0 requirement due to something failing on 4.2 or did you just ignore 4.2 from the start?
Hi,
I've just tried the GraphiQL support. It seems to work, a bit. I can query my GraphQL schema through it.
But unfortunately:
invariant@https://unpkg.com/[email protected]/graphiql.min.js:11:7912
defineFieldMap@https://unpkg.com/[email protected]/graphiql.min.js:12:9851
getFields@https://unpkg.com/[email protected]/graphiql.min.js:12:14838
https://unpkg.com/[email protected]/graphiql.min.js:13:12924
typeMapReducer@https://unpkg.com/[email protected]/graphiql.min.js:13:13087
reduce@[native code]
e@https://unpkg.com/[email protected]/graphiql.min.js:13:16026
buildClientSchema@https://unpkg.com/[email protected]/graphiql.min.js:14:5879
https://unpkg.com/[email protected]/graphiql.min.js:1:29756
promiseReactionJob@[native code]
Also, I noticed that the Docs pane does not load, and I cannot use autocomplete. So something seems to be going wrong here. Any clue?
The browser console shows no errors though.
Kind regards,
Sander
I am looking to perform the following type of query, where friends is a relationship of user. I see that it is possible to nest a relationship (https://github.com/Folkloreatelier/laravel-graphql#eager-loading-relationships) but I am wondering if it is possible to query a relationship. If so can you please provide a code example.
Thanks
Hey,
I wanna know how I can give back a string as an actual json object and not as an escaped string from a table's column? Is there a way to achieve this?
This is more of an suggestion, but I have a custom field that requires arguments and I'd like to use the built-in validation. It only took me a few minutes to realize that a Mutation is nothing more than of Field that has rules applied. I simply switched my Field to extend a Mutation instead and everything works fine, but I'm wondering if that logic could be placed in the Field and still have the Mutation type extend it just for naming purposes.
Alternatively, maybe the logic could be put into a trait which mutations use and the user can choose to add the trait to have validation run on a custom field's arguments (something like ShouldBeValidated).
Thanks!
Was going to work on this next week or the week after as we use this tool in a project.
The commands would, like other generators, allow the user to make the model from the command line.
php artisan make:graphql:type UserType
That would then make the files, folders if needed, and update the config file as well.
php artisan make:graphql:query UsersQuery
Same here.
The user would fill in the args and resolve though later can add options.
Let me know if this is not something already in your planning and I will continue on with it.
Thanks!
I have followed the Readme for eager loading
public function resolve($root, $args, ResolveInfo $info)
{
$fields = $info->getFieldSelection($depth = 3);
$users = User::query();
foreach ($fields as $field => $keys) {
if ($field === 'team') {
$users->with('team');
}
}
return $users->get();
}
This query runs successfully in my app.
[2015-11-12 11:22:46] View Logs.INFO: select * from `teams` where `teams`.`id` in (?, ?, ?) [1,2,3] []
And in my UserType
class I have the following in the fields
function
'team' => [
'type' => Type::listOf(GraphQL::type('team')),
'description' => 'The users team',
]
I am getting the following error:
User Error: expected iterable, but did not find one.
If I add a resolve
function to the team array it works but I then loose the eager loading functionality:
'team' => [
'type' => Type::listOf(GraphQL::type('team')),
'description' => 'The users team',
'resolve' => function($data, $args) {
return $data->team()->get();
}
]
Is there any way to share $root between mutations? Something like:
https://github.com/webonyx/graphql-php/blob/master/tests/Executor/MutationsTest.php#L68-L85
Since mutations are executed serially in the order given, I'm trying to achieve something like the following (source article):
mutation something {
loginWithToken(token: "6e37a03e-9ee4-42fd-912d-3f67d2d0d852"),
do_stuff(greeting: "Hello", name: "Tom"),
do_more_stuff(submarine_color: "Yellow")
}
Where the user is authenticated in the first mutation, and stays "available" for all subsequent ones.
I tried this idea and $root seems to be null
inside my mutation's resolve()
method!
Any tips are appreciated, thanks for reading ๐
Has anyone successfully added auth middleware to the graphql
endpoint? I am working on a clean Laravel 5.3
installation. Auth middleware is working for the rest of the app. GraphQL (and GraphiQL) are integrated and working fine. When I try adding:
'middleware' => [ 'auth' ]
to my graphql.php
config file I cannot seem to get past the un-authenticated response.
Schema generator needed for relay js transpilling.
I am getting the following error when following the examples you have written out on the readme.
ErrorException in Schema.php line 61:
GraphQL\Schema constructor expects config object now instead of types passed as arguments. See webonyx/graphql-php#36
You need to make folklore/graphql/src/Folklore/GraphQL/GraphQL.php:70
send an array in the form of this:
return new Schema(['query' => $queryType, 'mutation' => $mutationType]);
Thanks for this package I am facing two problems
The first one:
I need the output to be something like this:
{
"total": 102,
"per_page": 10,
"current_page": 1,
"last_page": 11,
"next_page_url": "http://local.api.htr.com//api/v1/restaurant?page=2",
"prev_page_url": null,
"from": 1,
"to": 10,
"data": [
{
"id": 221,
"owner_id": 691,
"slug": "kfc2",
"type": 1,
}
]
}
The second problem is that I need to fetch the data from apis not from elouqant
Thanks
Is there any way to set the HTTP status code from the resolve()
method? I know GraphQL can return "partial success", but it'd be nice to be able to take advantage of the tool that HTTP provides us ๐
I like how the graph-php and this package catch errors during the query and places the message in the payload. It does not however preserve the response status code set or $code attribute in the error object.
Any chance this can be done?
Hey,
I have a GraphQL Api and I wanna protect some queries with with this recently introduced API Authentication:
https://laravel.com/docs/5.3/passport
But I only want to protect certain queries, not all of them, as there are a few public ones. Is this possible yet and if so, how?
Thank you for your work on this package. I am very excited to use.
I am sorry to make an issue but I'm just learning relay (as most are atm) and I followed your instructions on the readme exactly however I get the following error message when visiting my .../graphql?query=query+FetchUsers{users{id,email}} .
{ "errors": [ { "message": "Cannot query field users on Query", "locations": [ { "line": 1, "column": 18 } ] } ] }
Error message isn't very helpful to me and I'm not sure where to look to dig deeper. I'm on Ubuntu 15.04, Laravel 5.* using Homestead VM.
You can provide sensible defaults and allow people to add their own config data outside of their vendor directory this way.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.