Hasura: Allow-list configuration - graphql

I'm trying to setup the allow list feature in Hasura, but the docs seem pretty sparse. This is one of the queries:
{
hasura_auth(args: {cleartext_password: "xxx", email: "email#mail.com"}) {
jwt_token
}
}
How would I integrate the dynamic parts in an allow list?
I tried this and lot's of variations with no luck:
{
hasura_auth(args: {cleartext_password: $pass, email: $email}) {
jwt_token
}
}
Thanks for your help!

What you have to know is to tell hasura the name of your query with full syntax.
like this...
Operation name is => get_user_by_pk
Operation is
query get_user_by_pk($id: uuid!) {
user_by_pk(id: $id) {
id
username
email
}
}
the main part is you have to use the exact operation in your code having the operation name.
now, in your project, you will send the variable (in this case id[uuid]) to the query handler and send this to your hasura server.
ask me if it is not clear for you.

Related

Getting Unsupported token `on` [GraphQL]

Issue: We goto 'on' in the query, while build apollo is complaining about the on keyword in the query (*.graphql)
GraphQL query:
query TimeLine($inputData: InputData!) {
getTimeLine(inputData: $inputData) {
on
updated
}
}
Error: Unsupported token on
(com.apollographql.apollo.compiler.parser.GraphQLDocumentParseException).
Env: Kotlin, apolloGraphQLVersion: "1.3.2"
This happens because the on keyword is a reserved keyword in GraphQL.
One of the Type Conditions is on NamedType, see the official spec file of GraphQL.
query FragmentTyping {
profiles(handles: ["zuck", "cocacola"]) {
handle
...userFragment
...pageFragment
}
}
fragment userFragment on User {
friends {
count
}
}
fragment pageFragment on Page {
likers {
count
}
}
See the on used in fragment userFragment on User? Your GraphQL got confused because you are using on as a field within the query, while it expects to be a fragment. Read more about fragments here. Also, a fragment's name can be anything, except for on, see the official spec file.
One way to solve this issue might be to rename the field in your query, but I am not sure if GraphQL will complain about this approach as well:
query TimeLine($inputData: InputData!) {
getTimeLine(inputData: $inputData) {
dataOn: on
updated
}
}

How can I create an issue with github GraphQL API?

I'm starting to use GraphQL API and I've seen that the mutation createIssue was recently added but I don't know how to use it. I've tried the following but I'm getting errors:
mutation {
createIssue(input:{
repositoryId:"XXXXXXXXXXXX",
assigneeIds:"XXXXXXX",
title:"TestIssue",
body:"Not able to create an issue"})
}
You need first to get the repository id using the following request:
query FindRepo {
repository(owner: "johndoe", name: "awesome-repo") {
id
}
}
Then you call the mutation request by replacing the id you've got in the response in repositoryId field :
mutation CreateIssue {
createIssue(input: {repositoryId: "[ID from previous call]", title: "TestIssue", body: "Not able to create an issue"}) {
issue {
number
body
}
}
}
You can try both call in the graphql explorer and running first the FindRepo request and then CreateIssue
Or you can do it like this:
As the previous answer said, you have to find the repositoryId first, or you will met the error in the image.
And further more, when you have any issues finding a way to do mutation or query, you can find your answer in the Doc section in the right of the github explorer.

Is it possible for vue-apollo to return different results from the Playground?

I have a GraphQL query called myAccounts which returns an array of accounts. When I go to the Playground and call the query:
{
accounts {
email
}
}
I get this result:
"data": {
"accounts": [
{
"email": "zach#email-one.com",
},
{
"email": "zach#email-two.com",
}
]
}
However, when I am in my Component, vue-apollo returns two items in the array, but seems to overwrite the second item with the first. Here is the query (in MyAccounts.gql):
query myAccounts {
accounts: myAccounts {
email
}
}
and here is the Apollo query in the component:
import MY_ACCOUNTS_QUERY from '~/apollo/queries/MyAccounts'
...
apollo: {
accounts: {
query: MY_ACCOUNTS_QUERY,
result(data) {
console.log(JSON.stringify(data))
}
}
}
and here is what vue-apollo logs out through the result:
{
"data":{
"accounts":[
{
"email":"zach#email-one.com",
"__typename":"Account"
},
{
"email":"zach#email-one.com",
"__typename":"Account"
}
]
},
"loading":false,
"networkStatus":7,
"stale":false
}
Expected behavior
I would expect the data returned in the Playground to be identical to what vue-apollo is fetching.
Versions
vue: 2.6.10
vue-apollo: #nuxtjs/apollo: 4.0.0-rc18
Additional context
I thought the result hook would be the best way to debug, but any other suggestions gladly welcomed. I assumed that this was a bug in our code, but I cannot figure out what could be causing the repetition (and mismatch).
Apollo normalizes its cache based on the __typename and the id (or _id) field. You need to include an id or _id field in your selection set alongside email. Failing to do so results in both objects being assigned the same key. If you don't have an id field to request, you'll need to provide a custom dataIdFromObject function as shown here.
From Guillaume Chau (https://github.com/Akryum):
This is because the Apollo Client cache can't compute a different ID
for the two items, so you endup with Account:undefined (or similar)
for both. Open the Apollo devtools and look at the myAccounts key in
the cache.
Learn more:
https://www.apollographql.com/docs/react/caching/cache-configuration/

Resolve to the same object from two incoherent sources in graphql

I have a problem I don't know how to solve properly.
I'm working on a project where we use a graphql server to communicate with different apis. These apis are old and very difficult to update so we decided to use graphql to simplify our communications.
For now, two apis allow me to get user data. I know it's not coherent but sadly I can't change anything to that and I need to use the two of them for different actions. So for the sake of simplicity, I would like to abstract this from my front app, so it only asks for user data, always on the same format, no matter from which api this data comes from.
With only one api, the resolver system of graphql helped a lot. But when I access user data from a second api, I find very difficult to always send back the same object to my front page. The two apis, even though they have mostly the same data, have a different response format. So in my resolvers, according to where the data is coming from, I should do one thing or another.
Example :
API A
type User {
id: string,
communication: Communication
}
type Communication {
mail: string,
}
API B
type User {
id: string,
mail: string,
}
I've heard a bit about apollo-federation but I can't put a graphql server in front of every api of our system, so I'm kind of lost on how I can achieve transparency for my front app when data are coming from two different sources.
If anyone has already encounter the same problem or have advice on something I can do, I'm all hear :)
You need to decide what "shape" of the User type makes sense for your client app, regardless of what's being returned by the REST APIs. For this example, let's say we go with:
type User {
id: String
mail: String
}
Additionally, for the sake of this example, let's assume we have a getUser field that returns a single user. Any arguments are irrelevant to the scenario, so I'm omitting them here.
type Query {
getUser: User
}
Assuming I don't know which API to query for the user, our resolver for getUser might look something like this:
async () => {
const [userFromA, userFromB] = await Promise.all([
fetchUserFromA(),
fetchUserFromB(),
])
// transform response
if (userFromA) {
const { id, communication: { mail } } = userFromA
return {
id,
mail,
}
}
// response from B is already in the correct "shape", so just return it
if (userFromB) {
return userFromB
}
}
Alternatively, we can utilize individual field resolvers to achieve the same effect. For example:
const resolvers = {
Query: {
getUser: async () => {
const [userFromA, userFromB] = await Promise.all([
fetchUserFromA(),
fetchUserFromB(),
])
return userFromA || userFromB
},
},
User: {
mail: (user) => {
if (user.communication) {
return user.communication.mail
}
return user.mail
}
},
}
Note that you don't have to match your schema to either response from your existing REST endpoints. For example, maybe you'd like to return a User like this:
type User {
id: String
details: UserDetails
}
type UserDetails {
email: String
}
In this case, you'd just transform the response from either API to fit your schema.

GraphQL non nested relation

I'm trying to have a representation of nodes on GraphQL more akin to what jsonapi would be like http://jsonapi.org/
What I mean is if we take one of the examples on GraphQL
{
hero {
name
# Queries can have comments!
friends {
name
}
}
}
Have a representation that would be more along these lines
{
hero {
name
# Queries can have comments!
friends {
id
}
},
friends {
id, name
}
}
Is that at all possible in GraphQL
Thanks
It is possible, and there's nothing wrong with having a friends field. In GraphQL terms you can have the following part of the schema:
type User {
id: ID
name: String
firends: [User]
}
type RootQuery {
hero: User
friends(forUserId: ID!): [User]
}
And then you can query this as you like – you can ask for friends separately:
{
friends(forUserId: "12") {
id, name
}
}
But the whole idea of GraphQL is that you don't have to do multiple queries to get the information you need. If you just need a list of users – that's a reasonable query, that most people have (with arguments for pagination and so on). With that said, there's no reason to fetch a list of IDs and to send another fetch query for the data right after that.

Resources