Laravel lighthouse JSON type - laravel

How can I add JSON type to lighthouse?
I've seen this package but I don't know how to use it and there's not any documentations available for it: https://github.com/mll-lab/graphql-php-scalars

Once you installed it, in your schema.graphql define every Scalar you want to use, like:
scalar JSON #scalar(class: "MLL\\GraphQLScalars\\JSON")
# Then just use it, like:
type User {
id: ID!
meta: JSON!
}

Related

How to define an arbitrary scalar in apollo gql?

I have a type that needs to be like the following
type ActivityPayload {
action: String!
extra: AnythingAtAll
}
Where AnythingAtAll is an arbitrary JSON format. So that's as far as I get because all the tutorials I see expect you to have a type AnythingAtAll with fields defined inside of it. How do I allow {}, or {any properties in json format no matter what the property names and values are}
Use graphql-scalars:
A library of custom GraphQL scalar types for creating precise type-safe GraphQL schemas.
This library offers also the scalar type JSON:
The JSON scalar type represents JSON values as specified by ECMA-404.
Then you can do the following:
type ActivityPayload {
action: String!
extra: JSON
}
See also graphql-type-json (JSON is based on this one).

How to require propertyA OR propertyB in a GraphQL Schema

In the type definition below, is there a way to require name or model, instead of name and model?
type Starship {
id: ID!
name: String!
model: String!
length(unit: LengthUnit = METER): Float
}
I may have name or model due to some legacy data limitations. I would rather enforce this at the GraphQL validation layer, rather than in code.
EDIT:
There is some good discussion about adding validation to the graphQL spec, which you can read here: https://github.com/graphql/graphql-js/issues/361
There are also a couple of libraries to extend validation:
https://github.com/xpepermint/graphql-type-factory
https://github.com/stephenhandley/graphql-validated-types
I'm going to stick with validating the types in code, at least until they add better support.
You could try to use union to represent name or model concept . As union only works with object type now , that means you have also model name and model as object type first.
Code wise the schema looks like :
type Name {
value : String!
}
type Model {
value : String!
}
union NameOrModel = Name | Model
type Starship {
id: ID!
nameOrModel : NameOrModel!
length(unit: LengthUnit = METER): Float
}
It is very ugly IMO as it introduces many unnecessary noise and complexity to the schema .So I would prefer to stick with your original schema and do that check manually in the backend.
From the spec:
By default, all types in GraphQL are nullable; the null value is a valid response for all of the above types. To declare a type that disallows null, the GraphQL Non‐Null type can be used. This type wraps an underlying type, and this type acts identically to that wrapped type, with the exception that null is not a valid response for the wrapping type. A trailing exclamation mark is used to denote a field that uses a Non‐Null type like this: name: String!.
An individual field may be nullable or non-nullable. Non-null validation happens at the field level, independent of other fields. So there is no mechanism for validating whether some combination of fields are or are not null.

Can one have different types for same field between Prisma GraphQL schema and datamodel?

I'm a newbie to Prisma/GraphQL. I'm writing a simple ToDo app and using Apollo Server 2 and Prisma GraphQL for the backend. I want to convert my createdAt field from the data model to something more usable on the front-end, like a UTC date string. My thought was to convert the stored value, which is a DateTime.
My datamodel.prisma has the following for the ToDo type
type ToDo {
id: ID! #id
added: DateTime! #createdAt
body: String!
title: String
user: User!
completed: Boolean! #default(value: false)
}
The added field is a DataTime. But in my schema.js I am listing that field as a String
type ToDo {
id: ID!
title: String,
added: String!
body: String!
user: User!
completed: Boolean!
}
and I convert it in my resolver
ToDo: {
added: async (parent, args) => {
const d = new Date(parent.added)
return d.toUTCString()
}
Is this OK to do? That is, have different types for the same field in the datamodel and the schema? It seems to work OK, but I didn't know if I was opening myself up to trouble down the road, following this technique in other circumstances.
If so, the one thing I was curious about is why accessing parent.added in the ToDo.added resolver doesn't start some kind of 'infinite loop' -- that is, that when you access the parent.added field it doesn't look to the resolver to resolve that field, which accesses the parent.added field, and so on. (I guess it's just clever enough not to do that?)
I've only got limited experience with Prisma, but I understand you can view it as an extra back-end GraphQL layer interfacing between your own GraphQL server and your data (i.e. the database).
Your first model (datamodel.prisma) uses enhanced Prisma syntax and directives to accurately describe your data, and is used by the Prisma layer, while the second model uses standard GraphQL syntax to implement the same object as a valid, standard GraphQL type, and is used by your own back-end.
In effect, if you looked into it, you'd see the DateTime type used by Prisma is actually a String, but is likely used by Prisma to validate date & time formats, etc., so there is no fundamental discrepancy between both models. But even if there was a discrepancy, that would be up to you as you could use resolvers to override the data you get from Prisma before returning it from your own back-end.
In short, what I'm trying to say here is that you're dealing with 2 different GraphQL layers: Prisma and your own. And while Prisma's role is to accurately represent your data as it exists in the database and to provide you with a wide collection of CRUD methods to work with that data, your own layer can (and should) be tailored to your specific needs.
As for your resolver question, parent in this context will hold the object returned by the parent resolver. Imagine you have a getTodo query at the root Query level returning a single item of type ToDo. Let's assume you resolve this to Prisma's default action to retrieve a single ToDo. According to your datamodel.prisma file, this query will resolve into an object that has an added property (which will exist in your DB as the createdAt field, as specified by the #createdAt Prisma directive). So parent.added will hold that value.
What your added resolver does is transform that original piece of data by turning it into an actual Date object and then formatting it into a UTC string, which conforms to your schema.js file where the added field is of type String!.

apollo-codegen output is empty

I'm running into a situation in which apollo-codegen is not successfully generating typescript code.
For the graphql file (generated/schema.graphql):
type Author {
id: Int!
firstName: String
lastName: String
posts: [Post]
}
type Post {
id: Int!
title: String
author: Author
votes: Int
}
I then run :
$apollo-codegen introspect-schema generated/schema.graphql --output generated/schema.json
this generates a ./generated/schema.json that appears to contain the relevant information (I see information about Author and its properties, and Post and its properties).
I then run
$apollo-codegen generate generated/schema.graphql --schema generated/schema.json --target typescript and get an (effectively) empty output.
// This file was automatically generated and should not be edited.
/* tslint:disable */
/* tslint:enable */
I've tried generating .swift files as well, with similar empty output.
Apollo codegen version is:
"apollo-codegen": "^0.11.2",
Anyone see if what I'm doing wrong?
I'm a collaborator on apollo-codegen. Happy to hear that you're giving it a try!
You're not seeing any output because apollo-codegen generates types based on the GraphQL operations (query, mutation) in your project -- not based solely on the types in your schema.
In our experience, it's very rare that you would send a query for a full GraphQL type. Instead, we have found types based on graphql operations to be the most useful.
For instance, given the types you've provided, you might write a query:
query AuthorQuery {
authors {
firstName,
lastName
}
}
The type that would get generated (and that you'd probably want to use in code that consumes the results of this query, is
type AuthorQuery = {
authors: Array<{
firstName: string,
lastName: string
}>
}
Notice how you would use the AuthorQuery type in your React component (or similar) whereas you wouldn't use an Author type since it would include more fields than you've actually requested.
If you do however have a use-case for a 1:1 type from your graphql schema to typescript, do file an issue on the project itself and I'd be happy to discuss there :)

Convert GraphQL shorthand notation to respective object?

I am working on a GraphQL server setup where it can parse Types passed into it from strings, and I am looking for a solution to convert a string to an appropriate object. For example, if the string here is passed in:
type User { id: String, name: String }
My function would return the equivelant of running this code:
new graphql.GraphQLObjectType({
name: 'User',
fields: {
id: { type: graphql.GraphQLString },
name: { type: graphql.GraphQLString },
}
});
The key here is to be agnostic, so I could also pass in say, interfaces, and other shorthand and have it return the appropriate object. I have gotten as far as achieving the Abstract Syntax Tree from the graphql/language module bu using graphql_language.parse(str) function, but I'm unsure where to go from here.
The reference GraphQL-JS implementation on GitHub already has a function, buildASTSchema, that takes a parsed type schema and creates a set of JavaScript objects. So the best way to see how to do it would be to consult that source code on GitHub: https://github.com/graphql/graphql-js/blob/master/src/utilities/buildASTSchema.js
Alternatively, perhaps your tool can be built using that function. Since that repository is maintained by the core GraphQL team, you can be pretty confident that it will be up to date with new additions to the spec.
Edit from comment: If what you're trying to do is generate an executable GraphQL schema/server from the type language string, then you can use the generateSchema function from the graphql-tools package, as documented here: http://docs.apollostack.com/apollo-server/generate-schema.html

Resources