Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support an official way to pass a Raw JSON String Query #188

Open
RickStrahl opened this issue Feb 22, 2019 · 4 comments
Open

Support an official way to pass a Raw JSON String Query #188

RickStrahl opened this issue Feb 22, 2019 · 4 comments
Labels
Status: Up for grabs Issues that are ready to be worked on by anyone Type: Feature New feature or request

Comments

@RickStrahl
Copy link

RickStrahl commented Feb 22, 2019

I'm trying to use the GraphQL API to retrieve content from a specific repository item via the GraphQL API.

I can enter a graphQL query into the explorer and it works:

image

I've been trying to figure out how to duplicate this behavior using the OctoKit GraphQL API to accomplish the same thing. I've not figured out a way to get the LINQ syntax to represent that query, but it appears that I can also send the text directly to connection.Run(lcJson).

[TestMethod]
        public async Task RawJsonTest()
        {
            var productInformation = new ProductHeaderValue("GraphQLTest", "0.1");
            var connection = new Connection(productInformation, token);

            string rawJson = @"query {
  repository(name: ""MarkdownMonster"", owner: ""RickStrahl"") {
    object(expression: ""master:README.md"") {
      ... on Blob {
        text
      }
    }
 }
}";

            var result = await connection.Run(rawJson);

            Assert.IsNotNull(result);
            Assert.IsTrue(result.Contains("\"text\": "));
        }

However this returns 400 Bad Request. Checking the request trace I can see the raw JSON is going out to the server and it all looks correct.

I would have expected that to work.

I turns out the query syntax needs to be more formal and require top level {query, variables } object to make this work so I can get it to work.

This actually works to retrieve the raw JSON:

       [TestMethod]
        public async Task RawJsonWithTestQueryTest()
        {
            var productInformation = new ProductHeaderValue("GraphQLTest", "0.1");
            var connection = new Connection(productInformation, token);


            string rawJson = @"
query {
  repository(name: ""MarkdownMonster"", owner: ""RickStrahl"") {
    object(expression: ""master:README.md"") {
      ... on Blob {
        text
      }
    }
 }
}";
            var query = new TextQuery(rawJson);
            string result = await connection.Run(query.ToString());

            Console.WriteLine(result);

            Assert.IsNotNull(result);
            Assert.IsTrue(result.Contains("\"text\":"));
        }
    }

but it's not exactly intuitive.

Ideally I would like to see the API syntax provide the strongly typed equivalent of the raw JSON, but I can't find any examples that work to perform the ... on syntax. I can drill into the object and get the Id but that's where it ends.

In the meantime it might be nice to provide some explicit support for raw Text in the API so as to make it obvious that can be provided and automatically handle at least wrapping up the query and variables.

Something like this perhaps:

     [TestMethod]
        public async Task RawJsonWithTestQueryTest()
        {
            var productInformation = new ProductHeaderValue("GraphQLTest", "0.1");
            var connection = new Connection(productInformation, token);


            string rawJson = @"
query {
  repository(name: ""MarkdownMonster"", owner: ""RickStrahl"") {
    object(expression: ""master:README.md"") {
      ... on Blob {
        text
      }
    }
 }
}";
            // Official object for raw Text Queries
            var query = new TextQuery(rawJson);

            // direct overload  w/o .ToString() requirement would be nice
            var result = await connection.Run(query.ToString());  

            Console.WriteLine(result);

            Assert.IsNotNull(result);
            Assert.IsTrue(result.Contains("\"text\":"));
        }
    }


    public class TextQuery 
    {
        private readonly string _queryText;
        private readonly Dictionary<string, object> _variables;

        public TextQuery(string queryText, Dictionary<string, object> variables = null)
        {
            _queryText = queryText;
            _variables = variables;
        }

        public override string ToString()
        {
            var query = new
            {
                query = _queryText,
                _variables = _variables
            };

            var json = JsonConvert.SerializeObject(query);
            return json;
        }

    }
@grokys
Copy link
Collaborator

grokys commented Feb 22, 2019

Hi @RickStrahl!

The LINQ-style query for your query would be:

            var query = new Query()
                .Repository(name: "MarkdownMonster", owner: "RickStrahl")
                .Object(expression: "master:README.md")
                .Cast<Blob>()
                .Select(x => x.Text);

Running the query as a string using connection.Run isn't really a scenario that we've tried to make easy to use. The issue with doing it like that that the client would be responsible for deserializing it into C# classes. It's not an issue in this case as you're querying a string, but most queries wouldn't do that and we'd have to give some thought as to how best to achieve this.

It's definitely something we could/should look into though.

@RickStrahl
Copy link
Author

Great! That worked perfectly.

So that solves the immediate problem I have here, but the question in the issue is still at point for whether there could be better support for raw JSON responses.

@StanleyGoldman
Copy link
Collaborator

Hey @RickStrahl we still think this is a valid desire. 😉

@github-actions
Copy link

github-actions bot commented Dec 4, 2022

👋 Hey Friends, this issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please add the Status: Pinned label if you feel that this issue needs to remain open/active. Thank you for your contributions and help in keeping things tidy!

@github-actions github-actions bot added the Status: Stale Used by stalebot to clean house label Dec 4, 2022
@kfcampbell kfcampbell added Priority: Normal Status: Up for grabs Issues that are ready to be worked on by anyone Type: Feature New feature or request labels Dec 5, 2022
@github-actions github-actions bot removed the Status: Stale Used by stalebot to clean house label Dec 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Up for grabs Issues that are ready to be worked on by anyone Type: Feature New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants