Solved

[Noob] How to call GraphQL API programmatically?

MarcoDo
Shopify Partner
19 4 8

I want to add a scripttag to an Onlinestore, and I managed to do it with the GraphQL explorer/app.

But I am completely lost in how to do it programmatically in my app, and the Shopify documentation doesn't really help me.

My goal: When a merchant presses a button in his admin page, I want my app to post a scripttag to this store.

I have created the an app with the Shopify App CLI.

In the server folder the CLI creates (these are the parts I suspect are important)

//this is in file "server.js"
router.post("/graphql", verifyRequest(), async (ctx, next) => {
    await Shopify.Utils.graphqlProxy(ctx.req, ctx.res);
  });

In server/handlers/mutations/ 

The CLI creates two files "get-subscription-url.js" and "get-one-time-url.js" where Graph Ql calls are done.

However, I dont understand how the frontend (the pages folder) can make these API calls.

If the merchant presses a button, how can I let apollo make a mutation api call? How is it authenticated?

Or do I (somehow) have to pass the API Call request to my backend, the server folder (maybe the route /graphql ?), so that the backend executes the mutation/query?

Accepted Solution (1)

MarcoDo
Shopify Partner
19 4 8

This is an accepted solution.

I figured it out and want to share if somebody has the same problem in the future.

First of all, I used the "useMutation" and "useQuery" function like the apollo docs say. So I didnt do it the way the tutorial proposes with <Query> / <Mutation> Components.

So, the frontend is able to make the call since in the _app.js file, the shopify CLI writes the code to authenticate and create the ApolloClient, which is then wrapped around your app in the <ApolloProvider> component. So when you make mutations/queries, you do not have to make any authentication or anything, you can just call these functions.

In my case, I wanted to add a ScriptTag to a store, after a merchant presses a button. 

I only changed .env file (added "write_script_tags" permission) and index.js file (see below how to make the mutation)

const ADD_SCRIPTTAG = gql`
mutation scriptTagCreate($input: ScriptTagInput!) {
  scriptTagCreate(input: $input) {
    scriptTag {
      id
    }
    userErrors {
      field
      message
    }
  }
}
`;
const inputVar = {
  "input": {
    "src": "https://your-url/script.js"
  }
}

const Index = () => {
  
  const [addScript, data] = useMutation(ADD_SCRIPTTAG);

  const testFunc = async () =>{
    await addScript({ variables: inputVar})
    console.log(data)

  }

  return (
  <Page>
    <Heading>Shopify app with Node and React 🎉</Heading>
    <Button onClick={() => testFunc()}>Button</Button>
  </Page>
  )
};

export default Index;

 

View solution in original post

Replies 7 (7)

MarcoDo
Shopify Partner
19 4 8

This is an accepted solution.

I figured it out and want to share if somebody has the same problem in the future.

First of all, I used the "useMutation" and "useQuery" function like the apollo docs say. So I didnt do it the way the tutorial proposes with <Query> / <Mutation> Components.

So, the frontend is able to make the call since in the _app.js file, the shopify CLI writes the code to authenticate and create the ApolloClient, which is then wrapped around your app in the <ApolloProvider> component. So when you make mutations/queries, you do not have to make any authentication or anything, you can just call these functions.

In my case, I wanted to add a ScriptTag to a store, after a merchant presses a button. 

I only changed .env file (added "write_script_tags" permission) and index.js file (see below how to make the mutation)

const ADD_SCRIPTTAG = gql`
mutation scriptTagCreate($input: ScriptTagInput!) {
  scriptTagCreate(input: $input) {
    scriptTag {
      id
    }
    userErrors {
      field
      message
    }
  }
}
`;
const inputVar = {
  "input": {
    "src": "https://your-url/script.js"
  }
}

const Index = () => {
  
  const [addScript, data] = useMutation(ADD_SCRIPTTAG);

  const testFunc = async () =>{
    await addScript({ variables: inputVar})
    console.log(data)

  }

  return (
  <Page>
    <Heading>Shopify app with Node and React 🎉</Heading>
    <Button onClick={() => testFunc()}>Button</Button>
  </Page>
  )
};

export default Index;

 

AsiaSell
Excursionist
50 0 5

Hi. I really appreciate you posting up your method. I'm also quite a [NOOB] as will be evident! When I replace the contents of the index.js file with your code I get ReferenceError: gqp is not defined. Any ideas?

MarcoDo
Shopify Partner
19 4 8

Hi, when you receive this error, most of the time its because you have not imported the module. (I assume your error is "ReferenceError: gql is not defined")

You resolve this by putting "

import gql from 'graphql-tag';
" on top of your file. Notice that this only works, if you have the 'graphql-tag' package already installed. If you didn't, google it and you will find instructions on how to install it. (Usually you do this with npm or yarn)

 

AsiaSell
Excursionist
50 0 5

Thanks for the reply! Yes, I meant gql, not gqp. I did what you said and it skips that error as you said. Before you replied I had ...

import { gql } from "apollo-boost";
 

Both of them allow gql to be defined, but now I have different errors for each and I'm hoping you might assist me again? I'm just including the apollo-boost because I really have little clue at this stage and I'm keeping my options open.

For import gql from 'graphql-tag'I have error useMutation is not defined. I tried and couldn't find how to define that.

For  import { gql } from "apollo-boost"I have error TypeError: Cannot read property 'bind' of undefined.

btw I noticed your code looks very different to the get-subscription-url.js and get-one-time-url.js files in the cli (they contain mutations). I tried doing it like that and haven't had any luck yet.

AsiaSell
Excursionist
50 0 5

Apologies, when I use import { gql } from "apollo-boost" I get useMutation is not defined. I left off the brackets in the post above.

JayCazaubon
Visitor
1 0 0

Can you provide an example of how you would make a query?

AsiaSell
Excursionist
50 0 5

I was just trying to make button clicks in my cli app work. This was just something I was trying and really didn't know how to use it.