How to query a third party package trait in Laravel lighthouse - laravel

I read Laravel Lighthouse documentation and searched around the web I did not find how to query a trait in a third party package in Laravel.
I'm using the qirolab/laravel-reactions package, it has the reactionSummary() trait.
I was asking how can I add this relation in the lighthouse query?
type Post {
id: ID!
title: String!
excerpt: String!
image_url: String!
slug: String!
source: Source! #belongsTo
reactionSummary: ???????
created_at: DateTime!
updated_at: DateTime!
}
I have a purpose with my question beside solving my issue, understanding how lighthouse work with packages or how to integrate third party packages with lighthouse?

You need to define the schema for the reaction model in graphql and in the post schema you need to define an array of the reaction type.
According to the model (https://github.com/qirolab/laravel-reactions/blob/master/src/Models/Reaction.php) the reaction graphql schema would look something like this:
type Reaction {
reactBy: User! #belongsTo
type: String
reactable: Reactable! #morphTo
}
Your post schema would change to
type Post {
id: ID!
title: String!
excerpt: String!
image_url: String!
slug: String!
source: Source! #belongsTo
reactionSummary: [Reaction]
created_at: DateTime!
updated_at: DateTime!
}
As I can see from the migration file https://github.com/qirolab/laravel-reactions/blob/master/migrations/2018_07_10_000000_create_reactions_table.php. The reaction has a polymorphic relation.
That means the returning type can vary depending on which kind of model is set as the reactable_type in the field. Therefore you need to define your own Union type.
A Union is an abstract type that simply enumerates other Object Types. They are similar to interfaces in that they can return different types, but they can not have fields defined.
Source: https://lighthouse-php.com/5/the-basics/types.html#union
See also polymorphic relations and the union section: https://lighthouse-php.com/5/eloquent/polymorphic-relationships.html#one-to-one
I hope that gives you the direction on how you can proceed.

Related

Introducing a "Connecting" Type in GraphQL

In my graphql schema, I have the two following (abbreviated) types.
type author {
id: Int!
name: String!
articles: [article!]
}
type article {
id: Int!
title: String!
abstract: String!
createdAt: DateTime!
}
That is to say, one author has many articles.
A new requirement has come in, which is to also show whether the author is the first or last named author on the article. How best to introduce this information into the schema without it being a breaking change? The following applies.
Both author and article have other relationships not shown. It doesn't make logical sense to have the new information sit directly on the article.
The information on the authors position in the article is in the link table in the database. Conceptually there is the author <-> author_article <-> article tables with the many to many illustrating the fact one author can publish many articles, and articles can have many authors. Ideas I've had.
Simply change the schema to the following.
type author {
id: Int!
name: String!
articles: [article!]
articleInformation: [articleInformation!]
}
type articleInformation {
firstAuthorship boolean
lastAuthorship boolean
article article
}
type article {
id: Int!
title: String!
abstract: String!
createdAt: DateTime!
}
to allow the querier to get the articleInformation if they choose, but this feels somewhat clunky.
use something like an interface that a normal article, and an "articleWithInformation" can implement.
Can someone with more experience than me at working with graphql offer some insight?

Laravel lighthouse graphql query by relation table value

Is it possible in Laravel lighthouse GraphQL to query by relation table values?
For example, I have defined two types.
type Translation {
id: ID!
form_group_id: Int!
group: Group #hasOne
translation_key: String!
lv: String
en: String
ru: String
}
type Group {
id: ID!
name: String!
translations: [Translation]! #hasMany
}
and I want to query by group name.
The code below is just an example of the idea.
translation(group.name: String! #eq): Translation #find
I have an idea that this, can be possible with custom resolver, but is there a way using built in eloquent resolvers?
Event tho this is an experimental feature, you can use complex where conditions. This will allow you to fetch whatever type by its relation attributes. We use it on our application, and for the use we have, this is working as expected :)

GraphQL - Model(s) belong to specific user field

I'm using Lighthouse package to implement GraphQL, the users in my app belong to an entity and I need to get models that belong to the entity of each user, my schema is like this for the moment
"A date string with format `Y-m-d`, e.g. `2011-05-23`."
scalar Date #scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\Date")
"A datetime string with format `Y-m-d H:i:s`, e.g. `2018-05-23 13:43:32`."
scalar DateTime #scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\DateTime")
type Query {
me: User #auth
execution: [RobotTime!]! #all
}
type RobotTime {
id: ID!
instance: Instance!
robot: Robot!
start: DateTime!
end: DateTime!
}
type Instance {
id: ID!
name: String!
token: String!
}
type Robot {
id: ID!
start_bot: String!
process: Process!
}
type Process {
id: ID!
name: String!
token: String!
}
type User {
id: ID!
name: String!
email: String!
created_at: String!
updated_at: String
}
I have searched the documentation, but I can't find anything that helps me to do what I need to do.
Currently I have it done in a controller and I return it as a json with a not so complex logic, there are about 5 models that I use.
Sorry for my bad English
You need to declare the appropriate relation in your User model in laravel, sth like this:
public function entity(): BelongsTo
{
return $this->belongsTo(Entity::class);
}
Then add the relation in User type in graphql:
type User {
id: ID!
name: String!
email: String!
created_at: DateTime!
updated_at: DateTime
entity: Entity #belongsTo
}
Of course, you'll need to declare an Entity model in laravel and type in graphql.

Do I have to create a new type to define array of objects in GraphQL schemas?

I’m trying to replicate a REST API that I’ve built in the past and one part that got me thinking was if one of my tables had an array of objects. So for example, I have a table called Profile and it contains arrays Experience and Education that would strictly be under Profile but has its own fields as well but not its own table.
While I was adding fields in GraphQL, I bumped into this not really having a solid solution other than to create new types and then associating them with relationships and then have a resolver or a front-end make sure a Profile is created first before the Experience/Education portion is. I’m not sure if it’s the right way to do it or if there is a better way to do it. Down below is a snippet of what I ended up using… looking at the admin page, there are created tables for Profile, Experience and Education which is expected. But is there a way to only have just Profile and accomplish something similar? Or is this more of a way of life with GraphQL?
type Profile {
id: ID! #id
handle: String!
company: String
website: String
location: String
status: String!
githubUsername: String
experience: [Experience!] #relation(link: INLINE)
education: [Education!] #relation(link: INLINE)
}
type Experience {
id: ID! #id
title: String!
company: String!
}
type Education {
id: ID! #id
title: String!
company: String!
}
In Prisma, you can use embedded types. You would drop the #relation directive and add #embedded directives to the types you're embedding:
type Profile {
id: ID! #id
handle: String!
company: String
website: String
location: String
status: String!
githubUsername: String
experience: [Experience!]
education: [Education!]
}
type Experience #embedded {
title: String!
company: String!
}
type Education #embedded {
title: String!
company: String!
}
However, this only possible if you're using MongoDB for your database and there's some specific limitations listed in the docs when using embedded types.

GraphQL Prisma - define "vote" type that links to two users

I've just started using Prisma. Before was mainly using firebase and mongodb to define my schemas.
I'm trying to define the following schema:
Vote {
id: ID!
from: User! # The user who voted
for: User! # The user that received a vote
rate: Float!
}
Basically, what I want to achieve is enable users to vote for other users (give them a score).
In, say, MongoDB I would do it by creating a separate collection like following:
{
id: DocumentID
from: String // id of the user who voted
for: String // id of the user that received a vote
rate: Number
}
In here I just specify those fields (from and for) as strings and after link them with the User collection by the application logic.
For sure, it's gonna be different in GraphQL Prisma. But I'm still a bit confused on how the relationships are built. And what really happens underneath.
How can I create such schema using Prisma GraphQL?
When there are more than one relational field to the same type, you need to use the #relation directive to make it unambiguous.
type Vote {
id: ID! #unique
votingUser: User! #relation(name: "VoteAuthor")
votedUser: User! #relation(name: "VoteReceiver")
rate: Float!
}
type User {
id: ID! #unique
receivedVotes: [Vote!]! #relation(name: "VoteReceiver")
givenVotes: [Vote!]! #relation(name: "VoteAuthor")
name: String!
}

Resources