Invoke Graphql query from Adobe IO

Shashi_Mulugu

MVP

06-10-2020

Hello Team,

 

Can anyone help us on how to invoke a Graphql query from Adobe IO runtime environment.

 

Basically we are trying to build an api layer in Adobe io which acts as middle layer between magento and other consuming applications such as AEM.

 

Any reference invocation or Pseudo code will help.

 

@mhaack @Mihai_Corlan 

Accepted Solutions (1)

Accepted Solutions (1)

mhaack

Employee

07-10-2020

Hi,

 

I suggest having a look at https://github.com/adobe/commerce-cif-graphql-integration-reference. This project is about exposing a GraphQL API based on the Magento schema. The schema you implement can be a subset or extensions of the Magento schema or a completely different GraphQL schema.

 

Markus

Answers (3)

Answers (3)

Nikhil-Kumar

MVP

07-10-2020

@Dragosche 

I am returning the Promise by resolving the output that I got from Magento:
So In the step just above where I am logging the output, it shows me the output but returns null although I returned it as a Promise.
Instead if I pass any static data it resolves fine.

 

get customer(){

        let output;
        return new Promise(async function(resolve,reject){
            try {
                output = await client.mutate({
                mutation: gql`mutation($email: String, $firstname: String, $lastname: String, $password: String) {
                    createCustomer(input: { email: $email, firstname: $firstname, lastname: $lastname, password: $password }) {
                        customer {
                            email
                            firstname
                            lastname
                                    }
                    }
                }
                
                    
                    `,
               variables
             });

             if(output && output.data && output.data.createCustomer && output.data.createCustomer.customer && output.data.createCustomer.customer.firstname){
                 ou = output.data.createCustomer.customer.firstname;
             }
            
             
           }
           catch(err){
               console.log('Error',err);
           }

           console.log('Output Data'output);
           resolve(output);

Dragosche

07-10-2020

@Nikhil-Kumar it seems to me like a javascript/Promise (miss)handling in the code. Using "return" directly won't wait for the Promise to complete. Using Promise's "resolve" is the right way to return a response. 

Please also make sure that your action returns a Promise. If it doesn't return a Promise, while invoking another javascript module which uses Promises, then javascript finishes your action before the other Promise finishes, hence returning a null object. 

Hoping this helps ! 

@Dragosche

@mhaack 

We are using something like below

async customer(){

let output;
let promise = new Promise(function(resolve,reject){
try {
output = client.mutate({
mutation: `My Graphql query`,
variables
});

}
catch(err){
console.log('Error',err);
}

resolve(output);


});

let result;
try{
result = await promise;
console.log('Returned data',result);
}
catch(error){
console.log('error',error);
}

let strData = JSON.stringify(result);
let fvalue;
if(strData){
let prse = JSON.parse(strData);
fvalue = prse.data.createCustomer.customer.email;
console.log('Logged ',fvalue);
}

let obj = {
email:fvalue,
firstname:"Nikhil",
lastname:"Kumar"
}

console.log('Object ',obj);

return Promise.resolve(obj);

}

 

 

If we see the logs, data gets properly logged in order and in the last object it before returning it contains the fetched email from the magento in the object as fvalue. 


Expected data in the final object when seen in logs should be :

{
    "data": {
        "createCustomer": {
            "customer": {
                "email""ndata45111f2581@gm.com",       ----> My fetched email from magento
                "firstname""Nikhil",
                "lastname""Kumar"
            }
        }
    }
}

But the returned response is: 

{
    "data": {
        "createCustomer": {
            "customer": {
                "email"null,                              -----> Response returned is different compared to logged object.
                "firstname""Nikhil",
                "lastname""Kumar"
            }
        }
    }
}



Test same scenario with REST api call, that works absolutely fine.(Thats also a async call). 


Nikhil-Kumar

MVP

07-10-2020

@mhaack -

We have extended the createCustomer in our resolvers and we are trying to call the magento and get the data as part of createCustomer call and return in as a response.
  
Our extended createCustomer entry point in cartResolver.js :

 createCustomer: (paramscontext=> {
            return new CreateCustomer({
                emailId: params.input.email
            });
 
From here we are calling a class with get customer method returning the response.
 
return new Promise(async function(resolve,reject){
let ou;
            try {
                output = await client.mutate({
                mutation: gql`mutation($email: String, $firstname: String, $lastname: String, $password: String) {
                    createCustomer(input: { email: $email, firstname: $firstname, lastname: $lastname, password: $password }) {
                        customer {
                            email
                            firstname
                            lastname
                                    }
                    }
                }
                
                    
                    `,
               variables
             });

             if(output && output.data && output.data.createCustomer && output.data.createCustomer.customer){
                 ou = output.data.createCustomer.customer;
             }
            
             
           }
           catch(err){
               console.log('Error',err);
           }
 
resolve(ou);
 
 
 
So we are getting the response from Magento Client in our Node JS code. It's just that, when we are returning it from Adobe IO endpoint it becomes null during the call. If any static response it gets resolved properly.

For ex: If I resolved the below object then I get the output:
let object =
{
            email:"ndata45111f2581@gm.com",
            firstname:'test',
            lastname:"Kumar"
  }
 
and when I add resolve(object) it gives me the proper response for create customer with static data:
{
    "data": {
        "createCustomer": {
            "customer": {
                "email""ndata45111f2581@gm.com",
                "firstname""test",
                "lastname""Kumar"
            }
        }
    }
}
 
 
But when I pass the returned response from Magento directly it resolves null. Although it logs the data.