Search code examples
reactjsgraphqlasp.net-core-2.0asp.net-core-webapigraphql-dotnet

How to call Grpahql with .Net core from a React component using Axios?


I am new to graphql and trying to implement Graphql with dot net core using graphql-dotnet library.

We do not have a dedicated database in this application. The high level flow of the application is

Front End(React) 
    (Calls) > GraphQlController (.Net core)
     (Calls) > Sales force api 
      Send data back to front end.

Graphql Setup.

public class GraphQLController : ControllerBase
    {
        private readonly IOptions<ApplicationConfiguration> _configuration;
        public GraphQLController(IOptions<ApplicationConfiguration> config)
        {
            this._configuration = config;
        }
        public async Task<IActionResult> Post([FromBody] GraphQLQuery query)
        {
            var inputs = query.Variables.ToInputs();

            var schema = new Schema()
            {
                Query = new OrderQuery(_configuration)
            };

            var result = await new DocumentExecuter().ExecuteAsync(_ =>
            {
                _.Schema = schema;
                _.Query = query.Query;
                _.OperationName = query.OperationName;
                _.Inputs = inputs;
            }).ConfigureAwait(false);

            if (result.Errors?.Count > 0)
            {
                return BadRequest();
            }

            return Ok(result);
        }
    }

Query class
 public class GraphQLQuery
    {
        public string OperationName { get; set; }
        public string NamedQuery { get; set; }
        public string Query { get; set; }
        public JObject Variables { get; set; }
    }

Model Class which used for the de-serialization

public class OrderModel
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }

Equivalent type in Graphql

public class OrderType : ObjectGraphType<OrderModel>
    {
        public OrderType()
        {
            Name = "Order";

            Field(x => x.Id).Description("The ID of the order.");
            Field(x => x.Name).Description("The name of the order");

        }
    }

The Query class to call the sales force service

public class OrderQuery : ObjectGraphType
    {

        public OrderQuery(IOptions<ApplicationConfiguration> config)
        {
            Field<OrderType>(
                "Order",
                arguments: new QueryArguments(
                           new QueryArgument<IdGraphType> { Name = "id" }),
                resolve: context =>
                {
                    var id = context.GetArgument<object>("id");
                    var service = new SalesForceService(config);
                    var data = service.GetAccountByAccountID(id.ToString());
                    return data;
                });
        }
    }

The application compiles fine in visual studio. when i press f5 and run this in the browser. I get this response

http://localhost:61625/api/graphql
{"":["The input was not valid."]}

When i try to run in postman by passing the following parameters in the body

{
OperationName:"test",
NamedQuery: "Orders",
Query:{},
Variables:{id:"123"}
}

i get this response ""A non-empty request body is required."

Can some one explain to me how do you make a request to graphql end point and what values should be passed in the below parms in postman.

{
OperationName:
NamedQuery: 
Query:,
Variables:
}

How do you make a similar call from react , We are using axios:. like below example how are parameters set for the call.

 doRestCall = (id) => {
        const model = {
            variable: id
        };

        const headers = {
            'Content-Type': 'application/json'
        }



        Axios.post('http://localhost:49776/api/graphql', model, headers)
            .then(result => {
                debugger;
                console.log(result);

            });
        console.log(this.state);
    };

Many thanks for the help.


Solution

  • It appears you're trying to use "named queries" with the use of NamedQuery, which is a design pattern with GraphQL. That design pattern is implemented by having well known queries that are pre-defined and cached on the server. Looking at your Controller you do not have named queries implemented. You will need to do a regular GraphQL query.

    This is what the JavaScript would look like:

    {
      query: "query MyOrderQuery($id: ID) { order(id: $id) { id name } }",
      variables: {
        id: "123"
      }
    }
    

    This would be the JSON:

    {
      "query": "query MyOrderQuery($id: ID) { order(id: $id) { id name } }",
      "variables": {
        "id": "123"
       }
    }
    

    See https://graphql-dotnet.github.io/docs/getting-started/variables

    I also suggest to use Apollo with your React components. https://www.apollographql.com/docs/react/essentials/get-started.html https://www.apollographql.com/docs/react/essentials/get-started.html#request