Coder Social home page Coder Social logo

gazuntype / graphql-client-unity Goto Github PK

View Code? Open in Web Editor NEW
286.0 14.0 49.0 20.48 MB

This repository houses a unitypackage that can be included in your Unity Project to enable it communicate with a graphQL server.

License: Apache License 2.0

C# 100.00%

graphql-client-unity's Introduction

graphQL-client-unity

graphQL-client-unity is, as the name implies, a graphQl client for the Unity game engine. Its major aim is to simplify the creation of graphQl queries and make graphQl features like subscriptions as straightforward as possible.

How it works

When imported, graphQl-client-unity allows the creation of queries within the Unity Editor. The client utilizes one of graphQl's amazing features, Introspection, to get all the queries, mutations, subscriptions, types and arguments from the graphQl schema. With this information, an easy-to-use editor layout allows the user to create queries by simply selecting from the available options within the editor. Each query created is stored in a scriptable object and can be used as many times as needed by simple calling one line of code.

UnityWebRequest request = await exampleApi.Post("QueryName", GraphApi.Query.Type.Query);

The client also utilizes different Events that can be subscribed to by any function. The Events are called when a request is completed, when data is gotten from a subscription and other useful cases.

How to use

Import UnityPackage

Download the unitypackage file and import it into your Unity project.

Create an API Reference

An API reference is a Scriptable Object that stores all the data relating to an API. For instance, if the API we intend to query is the Pokemon GraphQl API, within Unity, we would create an API Reference and point it to the url of the Pokemon GraphQl API. This API Reference will contain all the queries, mutations and subscriptions we wish to make pertaining to the Pokemon GraphQl API.

To create an API Reference, simply right click in your Asset folder, go to Create -> GraphQLClient -> API Reference. This would automatically create a new API Reference. Name it appropriately, put the url endpoint of the GraphQl API and click Introspect to begin creating queries.

Note: You'll need to Introspect every time to make changes to your GraphQl API to fetch the current schema.

Create an API Reference

Create a Query, Mutation or Subscription

To create a query, mutation or subscription is very intuitive and the processes are the same. Simply select Create Query (or Mutation, Subscription depending on your goal). Give the Query a name and pick the query from the dropdown menu displayed. After selecting the query you want to create, click confirm query and you can begin adding fields and subfields to the query. When you create a Query within the Editor, a Query object is created in the API Reference and this object houses all the information about that particular query.

Create a Query

Preview a Query

You can preview a query created to see how it looks as text. This is done simply by clicking the Preview Query button at the bottom of the query. Use the Edit Query button to go back to editing the query

Create a Query

Using the API Reference

To use an API reference to actually query APIs, you need to reference it within a script

using GraphQlClient.Core;

public GraphApi pokemonReference;

This allows you to drag and drop the API reference into the public field created in the Inspector. With the reference, you can query the API easily using the Post function

public async void GetPokemons(){
	UnityWebRequest request = await pokemonReference.Post("GetAllPokemons", GraphApi.Query.Type.Query);
}

The Post function returns a UnityWebRequest object and data gotten from the UnityWebRequest object can be gotten by

string data = request.downloadHandler.text;

This data is in JSON format and can easily be parsed using a tool like Unity's in-built JsonUtility class or third party JSON parsers like JSON. Net For Unity

Note: the Post function has three overloads.

Post(Query query) //takes in a Query object. this can be gotten by using GetQueryByName(string queryName, Query.Type type)

Post(string queryString) //takes in the query as a string input. this should be used if the query can't be formed in the editor

Post(string queryName, Query.Type type) //takes in the name of the query (created in the editor) and the type of query.

Setting Query Input

Due to the dynamic nature of query inputs, you cannot set them within the editor. Therefore input objects have to be created and the function Query.SetArgs(object input) is used to set the argument of that query.

public async void CreateNewUser(){
	//Gets the needed query from the Api Reference
        GraphApi.Query createUser = userApi.GetQueryByName("CreateNewUser", GraphApi.Query.Type.Mutation);
	
	//Converts the JSON object to an argument string and sets the queries argument
        createUser.SetArgs(new{objects = new{id = "idGiven", name = "nameGiven"}});
	
	//Performs Post request to server
        UnityWebRequest request = await userApi.Post(createUser);
}

Of course idGiven and nameGiven can be changed to any string.

Alternatively, you can use the overload function Query.SetArgs(string inputString) to set the input directly.

NOTE: The input object must be just like the input object in the APIs schema. For the example above, the query expected an input in this form insert_users(objects: {id: string, name: string}) where insert_user is the query name.

Authentication/Authorization

For authentication and authorization, the API reference has a function called GraphApi.SetAuthToken(string auth) which sets the Authorization header of all request made with that API reference.

Subscriptions

A subscription is created the same way as a query or a mutation. The only difference is instead of calling Post, you call Subscribe. The Subscribe functions does a lot of things under the hood like connecting websockets, observing the proper protocol and completing the handshake. While subscribed, you will continue to receive data from the server until you call CancelSubscription. The Subscribe function can take in a couple of arguments. socketId is the id you want to give the particular websocket. This is necessary if you want to have multiple subscriptions running at the same time. protocol is the sub protocol string used. The default value is graphql-ws. The Subscribe function returns a ClientWebSocket instance. You'd need this instance if you want to cancel a subscription with CancelSubscription. Each time the websocket receives data, an event OnSubscriptionDataReceived is called and this can be subscribed to to do anything. OnSubscriptionDataReceived has a variable data which contains the data received. An example is shown below that logs any data received from the subscription.

private void OnEnable(){
        OnSubscriptionDataReceived.RegisterListener(DisplayData);
}

private void OnDisable(){
        OnSubscriptionDataReceived.UnregisterListener(DisplayData);
}

public void DisplayData(OnSubscriptionDataReceived subscriptionDataReceived){
        Debug.Log(subscriptionDataReceived.data);
}

Events

For easy use, a couple of events have been created that can be subscribed to by functions. These events are called when specific things happen. A list of events created for the graphql-client are shown below. An Event can also contain some data relating to the event.

  • OnRequestBegin: This is called immediately a HTTP request is made.
  • OnRequestEnded: This is called when data from a HTTP request is gotten from the server. It contains the following variables:
    - bool success: This is true if the request was a success and false if there was an error.
    - string data: If bool success is true and the request succeeded, the data variable contains the data gotten from the request. If the request failed, the data variable is null.
    - Exception exception: If bool success is false, the request failed and the Exception called is passed into the exception variable.
  • OnSubscriptionHandshakeComplete: This is called when the protocol for the subscription is conducted successful and the handshake has been achieved.
  • OnSubscriptionDataReceived: This is called when data is gotten from a subscription. It contains the following variables:
    - string data: the data variable contains the data gotten from the subscription.
  • OnSubscriptionCanceled: This is called when a subscription has been successfully cancelled.

You can subscribe to these events by simply calling RegisterListener and you can unsubscribe by calling UnregisterListener. Here's an example where the OnRequestEnded event is used to get data from a request made.

private void OnEnable(){
        OnRequestEnded.RegisterListener(DisplayData);
}

private void OnDisable(){
        OnRequestEnded.UnregisterListener(DisplayData);
}

public void DisplayData(OnRequestEnded dataReceived){
        if (dataReceived.success){
		Debug.Log(dataReceived.data);
	}
	else{
		throw dataReceived.exception;
	}
}

NOTE: The function that subscribes to an Event must contain the Event class as an argument. Notice above with
public void DisplayData(OnRequestEnded dataReceived)

graphql-client-unity's People

Contributors

chefty avatar gazuntype avatar rushairer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graphql-client-unity's Issues

no graphql button in unity

dont work, if i click on create i dont get a button for graphql to include the api reference

unity 2021.03.21f1

WebGL Build

Is there a way to configure this package to work on a WebGL build? I need to perform GraphQL Queries, Mutation and Subscriptions all with Authorization Header on a WebGL application.

Variable of mutation related issue

Hello Guys, need a help with the mutation.

Here mutation:

mutation insert_user_assessment( $objects:
[user_assessment_insert_input!]!) {
insert_user_assessment(objects: $objects) {
returning {
id
  }
 }
}

Screenshot 2020-08-13 at 1 47 18 PM

This above mutation. Passing correct objects value as argument and access token given. I am executing. But have this error : {"errors":[{"message":"Internal server error","extensions":{"code":"INTERNAL_SERVER_ERROR"}}]}

Anyone have a solution or idea for this?

JsonToArgument function fails with valid input

I'm not 100% sure what is going on here, but I have been debugging for quite a while - was hoping to be able to submit a PR, but I hit a deadend.

Using SetArgs(object o) function, the Json conversation works fine (even with Enum), but then when JsonToArgument runs, and the following error happens:

System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

Based on the debugger, it seems that indexes has a Length(Count) of 1 here:

        if (jsonChar[i] == ':'){
            jsonChar[indexes[0]] = ' ';
            jsonChar[indexes[1]] = ' ';
        }

but it isn't clear exactly why. I added a check to make sure index[1] exists before running that second call to jsonChar[indexes[1]], but it results in a malformed query.

I made an isolated example on Repl.it if it is any help: https://repl.it/repls/AbleVerticalMaps

The input to the function is a direct copy of what is received after string json = JsonConvert.SerializeObject(inputObject, new EnumInputConverter());. In my schema I have an enum like AssetType:

enum AssetType {
  DRESSING
  GLOBAL
  MAP
  PLAYERHANDOUT
  TOKEN
  OTHER
}

and then in my local code:

enum AssetType {
  DRESSING
  GLOBAL
  MAP
  PLAYERHANDOUT
  TOKEN
  OTHER
}

I thought the enum might be the problem, because I have other queries that do work just fine. But I don't think AssetType enum is the problem here.

Code from Repl.it if it helps:

using System;
using System.Collections;
using System.Collections.Generic;

class MainClass {
  private static string JsonToArgument(string jsonInput){
    char[] jsonChar = jsonInput.ToCharArray();
    List<int> indexes = new List<int>();
    jsonChar[0] = ' ';
    jsonChar[jsonChar.Length - 1] = ' ';
    for (int i = 0; i < jsonChar.Length; i++){
        if (jsonChar[i] == '\"'){
            if (indexes.Count == 2)
                indexes = new List<int>();
            indexes.Add(i);
        }

        if (jsonChar[i] == ':'){
            jsonChar[indexes[0]] = ' ';
            jsonChar[indexes[1]] = ' ';
        }
    }

    string result = new string(jsonChar);
    return result;
  }

  public static void Main (string[] args) {
    JsonToArgument("{\"input\":{\"adventureId\":null,\"assetSubType\":null,\"assetType\":Map,\"campaignId\":null,\"contentPackageId\":null,\"description\":\"A wonderful place to go!\",\"encounterId\":null,\"name\":\"Abandoned House\",\"originalImageUrl\":\"https://i0.wp.com/www.fantasticmaps.com/wp-content/uploads/2010/06/Attachment-1.jpeg\",\"s3ImageUrl\":\"https://omitted.s3.amazonaws.com/08d7fa90-a716-4083-8fd6-41d21e317fe3/Attachment-1.47c282ef-8c42-4c29-8321-80360a2eaa36.jpeg\",\"userId\":\"08d7fa90-a716-4083-8fd6-41d21e317fe3\"}}");
  }
}

NullReferenceException

I'm getting this NullReferenceException every time after I play the unity editor and then click Create Field, also it makes the Create Field button in the inspector not visible. I'm using Unity 2019.3.3f1 version.

NullReferenceException: Object reference not set to an instance of an object
GraphQlClient.Core.GraphApi.AddField (GraphQlClient.Core.GraphApi+Query query, System.String typeName, GraphQlClient.Core.GraphApi+Field parent) (at Assets/graphQl-client/Scripts/Core/GraphApi.cs:240)
GraphQlClient.Editor.GraphApiEditor.DisplayFields (GraphQlClient.Core.GraphApi graph, System.Collections.Generic.List`1[T] queryList, System.String type) (at Assets/graphQl-client/Scripts/Editor/GraphApiEditor.cs:112)
GraphQlClient.Editor.GraphApiEditor.OnInspectorGUI () (at Assets/graphQl-client/Scripts/Editor/GraphApiEditor.cs:59)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass55_0.b__0 () (at <9a184ab867bb42c296d20ace04f48df3>:0)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

After re-introspecting w/ existing queries, return type changes to incorrect type

I have a query like GetUsers which is set to return user, but after I introspect, return type changes to character. Once this happens, when you click "add field", it causes all the values to be from the character schema instead.

I was able to "solve" this by deleting the query and making the exact same thing again - then the return type becomes correct.

Additionally, when you start building up these deep resolvers, you can imagine that re-creating these every time becomes a huge pain.

Is there no way to create the queries as text in files rather than this cumbersome tree UI?

Thanks!

Select type of Authentication

First off, kick ass package! This is absolutely amazing, phenominal work!! 🎉

I would like to request the ability to add what type of Auth is used when making requests. I noticed you've been using Bearer, however for the GraphQL APIs I'm using, the method we use is JWT.

It would be great if there was a AuthConstants.cs file, containing say

# AuthConstants.cs
public class AuthMethod {
   public const string BEARER = "Bearer";
   public const string JWT = "JWT";
...
}

and you could reference the Auth method you wished when setting the auth token, i.e.

myGraphQLReference.SetAuthToken(AuthMethod.BEARER, myToken);

Just a thought! Might save some others time who maybe aren't using Bearer as their source of API auth.

Thanks!!

'UnityWebRequestAsyncOperation' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter'

When I opened the demo project I get three errors from the HttpHandler... here are all three:

1.Assets\graphQl-client\Scripts\Core\HttpHandler.cs(31,17): error CS1061: 'UnityWebRequestAsyncOperation' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'UnityWebRequestAsyncOperation' could be found (are you missing a using directive or an assembly reference?)

2.Assets\graphQl-client\Scripts\Core\HttpHandler.cs(53,5): error CS1061: 'UnityWebRequestAsyncOperation' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'UnityWebRequestAsyncOperation' could be found (are you missing a using directive or an assembly reference?)

3.Assets\graphQl-client\Scripts\Core\HttpHandler.cs(75,17): error CS1061: 'UnityWebRequestAsyncOperation' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'UnityWebRequestAsyncOperation' could be found (are you missing a using directive or an assembly reference?)

Subscription support

Hi, thanks for sharing this code. I'm looking for a GraphQL client with subscription support. Does this client support subscriptions? If not, do you have plans to support them?

Request Error

Hi! Our backend team create schema with mutation

--data '{"query":"mutation Login { login(input: { email: "[email protected]", password: "aasdasd" })
{ __typename, ...on LoginAuthToken { accessToken refreshToken }, ...on InvalidCredentials
{ message } }}"}'

In unity inspector it look like

image

When I try to execute query i have error
GraphApi.Query query = _requests.GetQueryByName("Login", GraphApi.Query.Type.Mutation);
var result = await _requests.Post(query);
Debug.Log(result.downloadHandler.text);

{"errors":[{"message":"Field "login" of type "LoginUserResult!" must have a selection of subfields. Did you mean "login { ... }"?","extensions":{"code":"GRAPHQL_VALIDATION_FAILED","exception":{"stacktrace":["GraphQLError: Field "login" of
type "LoginUserResult!" must have a selection of subfields. Did you mean "login { ... }"?","
at Object.Field (/app/node_modules/graphql/validation/rules/ScalarLeafsRule.js:40:31)","
at Object.enter (/app/node_modules/graphql/language/visitor.js:323:29)","
at Object.enter (/app/node_modules/graphql/utilities/TypeInfo.js:370:25)","
at visit (/app/node_modules/graphql/language/visitor.js:243:26)","
at validate (/app/node_modules/graphql/validation/validate.js:69:24)","
at validate (/app/node_modules/apollo-server-core/dist/requestPipeline.js:187:39)","
at processGraphQLRequest (/app/node_modules/apollo-server-core/dist/requestPipeline.js:90:34)","
at runMicrotasks ()"," at processTicksAndRejections (node:internal/process/task_queues:96:5)","
at async processHTTPRequest (/app/node_modules/apollo-server-core/dist/runHttpQuery.js:187:30)"]}}}]}

Can you help me?

graphql via AWS Appsync

The current Unity AWS drivers don't support AppSync. Any plans to enable graphQL-client-unity to access AWS graphql?

JSONB Support

I think it just need this issue to be fixed to be able to send and retrieve jsonB parameters.

Also just saying, for something quoted on the Hasura website, it lacks basic features hasura have (JSONB, Where, Order By, Group By etc)

try / catch blocks hiding errors and bug in async/await extension

First: Thanks for building this!

I was having inconsistencies when using the latest pull. I realized it was related to two issues:
First: the try/catch blocks in httpHandler are actually consuming the exception and acting like everything is fine. An example proposed structure would look something closer to

public static async Task<UnityWebRequest> GetAsync(string url, string authToken = null){
            UnityWebRequest request = UnityWebRequest.Get(url);
            if (!String.IsNullOrEmpty(authToken)) 
                request.SetRequestHeader("Authorization", "Bearer " + authToken);
            OnRequestBegin  requestBegin = new OnRequestBegin();
            requestBegin.FireEvent();
            try{
                await request.SendWebRequest();
				OnRequestEnded requestSucceeded = new OnRequestEnded(request.downloadHandler.text);
				requestSucceeded.FireEvent();
				return request;
            }
            catch(Exception e){
                Debug.Log("Testing exceptions");
                OnRequestEnded requestEnded = new OnRequestEnded(e);
                requestEnded.FireEvent();
                throw;
            }
        }

Also your async/await library has a nullref bug in it....somewhere. Rather than debugging it - I tried using an extension method I found somewhere that's been super stable (been using it for years). Everything started showing up just fine after that. Feel free to steal it if you like:


public class UnityWebRequestAwaiter : INotifyCompletion
{
    private UnityWebRequestAsyncOperation asyncOp;
    private Action continuation;

    public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)
    {
        this.asyncOp = asyncOp;
        asyncOp.completed += OnRequestCompleted;
    }

    public bool IsCompleted { get { return asyncOp.isDone; } }

    public void GetResult() { }

    public void OnCompleted(Action continuation)
    {
        this.continuation = continuation;
    }

    private void OnRequestCompleted(AsyncOperation obj)
    {
        continuation();
    }
}

public static class ExtensionMethods
{
    public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
    {
        return new UnityWebRequestAwaiter(asyncOp);
    }
}

cheers!

Index was out of range Error

Current Behavior

Receiving ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. when I do the following:

int selectedStoreId = 0;
string createdDate;
...
object args = new {input = new{created = createdDate, store = new{id = selectedStoreId}}}; 
mutation.SetArgs(args);

Stacktrace

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <437ba245d8404784b9fbab9b439ac908>:0)
GraphQlClient.Core.GraphApi.JsonToArgument (System.String jsonInput) (at Assets/graphQl-client/Scripts/Core/GraphApi.cs:110)
GraphQlClient.Core.GraphApi+Query.SetArgs (System.Object inputObject) (at Assets/graphQl-client/Scripts/Core/GraphApi.cs:342)
CreateRecipt+<CreateNewRecipt>d__9.MoveNext () (at Assets/Resources/Scripts/CreateRecipt.cs:60)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) (at <437ba245d8404784b9fbab9b439ac908>:0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at /home/builduser/buildslave/unity/build/Runtime/Export/Scripting/UnitySynchronizationContext.cs:153)
UnityEngine.UnitySynchronizationContext:ExecuteTasks() (at /home/builduser/buildslave/unity/build/Runtime/Export/Scripting/UnitySynchronizationContext.cs:107)

Looking into this issue!

Api works in Unity Editor, but doesn't work on build

I am making a multiplayer game with Mirror, need to load several states for player with graph api.The local graphql URL is http://localhost:4000/graphql.It works smoothly in Unity Editor, but when I run a build locally as client , the api doesn't work.Even after I sign in build as host, it doesn't work either.I am not sure if i need modify the url when running on build.I tried many other ways, none works out.

Unexpected character encountered while parsing value

Queries made under GraphiQL editor throws error while trying to introspect. The error is:
JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.

Why does this happen?

Can't reset Authtoken

So with "API.myApiGraph.Set.AuthToken("myAuthToken") I can set my AccessToken as the Token used in the header when communicating with the server. Problem is when I log out and want to log in again the AuthToken is still set to the Access token so my Authentication process won't work anymore.

I tried setting it to "" or even to null but both doesn't seem to fully reset the header. Is there any way to reset it completely without restarting the App?

Stuck at introspect

Hello,upon importing graphQL into Unity,i got error regarding this line

  • " await request.SendWebRequest(); " in HttpHandler.cs
    It was UnityWebRequestAsyncOperation doesn't have await.So i change the line to make it have like so
  • "await request.SendWebRequest(); " => " await Task.Run(()=>request.SendWebRequest()); "
    And the error stop

After that,i check out the demo,hitting the introspect link on both pokemon and user.Both get stuck on " API is being introspect, please wait"
I even test it on a working project link and the bug remain

What should I do ?

Querying nested SetArgs()

I have a query in the format:

{
  System(ID: "1") {
    model {
      type {
        SystemModel{
          CreationModel(isModelCreated: true) {
          name
          }
         }
        }
     }
   }
}

And my Unity code is:

query.SetArgs (new { ID= "1", isModelCreated = true });

So in SetArgs, I have to provide a list of arguments, for example ID: "1" and isModelCreated: true. I am able to provide the first argument, but unfortunately the nested query's argument - isModelCreated is not getting recognized.

Authentication

I have modified this code to try to work with an authenticated server, but am having no luck passing the token, I keep getting a 401. What do you think I may be missing? See below:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using SimpleJSON;
using UnityEngine;
using UnityEngine.Networking;

namespace graphQLClient
{
    public class GraphQuery : MonoBehaviour
    {
        public static GraphQuery instance = null;
        [Tooltip("The url of the node endpoint of the graphQL server being queried")]
        public static string url;

        public delegate void QueryComplete();
        public static event QueryComplete onQueryComplete;

        public enum Status { Neutral, Loading, Complete, Error };

        public static Status queryStatus;
        public static string queryReturn;

        string authURL;
        public static string LoginToken;

        public class Query
        {
            public string query;
        }

        public void Awake()
        {
            if (instance == null)
            {
                instance = this;
            }
            else if (instance != this)
            {
                Destroy(gameObject);
            }

            DontDestroyOnLoad(gameObject);

            StartCoroutine("PostLogin");
        }

		private void Start()
		{
            LoginToken = "";
		}

		public static Dictionary<string, string> variable = new Dictionary<string, string>();
        public static Dictionary<string, string[]> array = new Dictionary<string, string[]>();
        // Use this for initialization

        // SMT Authentication to ELP
        // SMT Needed for Authentication---  if (token != null) request.SetRequestHeader("Authorization", "Bearer " + token);
        //POST https://myapp/login
        //In the request body: {email: string, password: string}
        //You’ll either get a 401 with an empty response or 201 with {token: string, user: object}
        IEnumerator PostLogin()//logs in to system
        {
            Debug.Log("Logging in...");
            string authURL = "myapp.com/login";
            string loginBody = "{\"email\":\"mylogin\",\"password\":\"mypasswor\"}";

            var request = new UnityWebRequest(authURL, "POST");
            byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(loginBody);
            request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
            request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");

            yield return request.SendWebRequest();

            if (request.isNetworkError || request.isHttpError)
            {
                Debug.Log("Login error!");

                foreach (KeyValuePair<string, string> entry in request.GetResponseHeaders())
                {
                    Debug.Log(entry.Value + "=" + entry.Key);
                }

                Debug.Log(request.error);
            }
            else
            {
                Debug.Log("Login complete!");
                //Debug.Log(request.downloadHandler.text);
                LoginToken = request.downloadHandler.text;
                Debug.Log(LoginToken);
            }
        }

        public static WWW POST(string details)//Supposed to after logging in to system, add token to body and then makes query
		{
            //var request = new UnityWebRequest(url, "POST");
			details = QuerySorter(details);
			Query query = new Query();
			string jsonData = "";
			WWWForm form = new WWWForm();
			query = new Query { query = details };
			jsonData = JsonUtility.ToJson(query);
			byte[] postData = Encoding.ASCII.GetBytes(jsonData);
			Dictionary<string, string> postHeader = form.headers;
            //postHeader["Authorization"] = "Bearer " + downloadHandler.Token;
            if (postHeader.ContainsKey("Content-Type"))

                //postHeader["Content-Type"] = "application/json";
                postHeader.Add("Authorization", "Bearer " + LoginToken);

            
			else
				postHeader.Add("Content-Type", "application/json");


            WWW www = new WWW(url, postData, postHeader);
			instance.StartCoroutine(WaitForRequest(www));
			queryStatus = Status.Loading;
			return www;
		}

		static IEnumerator WaitForRequest(WWW data)
		{
			yield return data; // Wait until the download is done
			if (data.error != null)
			{
				Debug.Log("There was an error sending request: " + data.error);
				queryStatus = Status.Error;
			}
			else
			{
				queryReturn = data.text;
				queryStatus = Status.Complete;
			}
			onQueryComplete();
		}

		public static string QuerySorter(string query)
		{
			string finalString;
			string[] splitString;
			string[] separators = { "$", "^" };
			splitString = query.Split(separators, StringSplitOptions.RemoveEmptyEntries);
			finalString = splitString[0];
			for (int i = 1; i < splitString.Length; i++)
			{
				if (i % 2 == 0)
				{
					finalString += splitString[i];
				}
				else
				{
					if (!splitString[i].Contains("[]"))
					{
						finalString += variable[splitString[i]];
					}
					else
					{
						finalString += ArraySorter(splitString[i]);
					}
				}
			}
			return finalString;
		}

		public static string ArraySorter(string theArray)
		{
			string[] anArray;
			string solution;
			anArray = array[theArray];
			solution = "[";
			foreach (string a in anArray)
			{

			}
			for (int i = 0; i < anArray.Length; i++)
			{
				solution += anArray[i].Trim(new Char[] { '"' });
				if (i < anArray.Length - 1)
					solution += ",";
			}
			solution += "]";
			Debug.Log("This is solution " + solution);
			return solution;
		}

	}
}

NullReferenceException: Object reference not set to an instance of an object GraphQlClient.Core.GraphApi.HandleIntrospection () (at Assets/graphQl-client/Scripts/Core/GraphApi.cs:134)

Hello, I am getting a NullReferenceException: Object reference not set to an instance of an object
GraphQlClient.Core.GraphApi.HandleIntrospection () (at Assets/graphQl-client/Scripts/Core/GraphApi.cs:134)
When I try to Introspect the url.

I inputted my key in the line below:

public void SetAuthToken(string auth){ authToken = "Mi_api_key";

I am getting that error, could it be because the URL I am trying to connect to requires for me to authenticate using my API key and API secret? They recommended using BasicAuth on their website.

How should I approach this?

Request for Non-GUI version

Due to GUI bugs referred to here
#6
and here
#10

I have a GUI version working on another machine but it doesn't work on my machine. The Api reference GUI crashes all the time on my machine and sometimes on another machine.

I attempted to create a non-GUI script but failed. Do you have a non-GUI script-only version available? Happy to compensate with some $.

Error parsing NaN value

Hi. I'm new to GraphQl. I want to do some fetch from https://axieinfinity.com/graphql-server/graphql, but whatever variation of the url i do (without https://, without the last graphql, with a / at the end, etc), i always get this:

JsonReaderException: Error parsing NaN value. Path '', line 1, position 1.

It must be something simple but i really wanna try this out...

Cheers

edit:
I'm now getting the same as the last post in here #6
The ScriptableObject UI is not showing, and the console spams NullRef in Assets/graphQl-client/Scripts/Core/GraphApi.cs:153
Restarting Unity doesn't help, the spam continues

How to use SetAuthToken?

I'm using bitquery to get some blockchain data and they said all I need is the X-API-KEY in the headers but I'm having trouble with the syntax. What am I doing wrong?

bqRef.SetAuthToken(@"""X-API-KEY"":""asdf1234""");

I'm getting this error "401 Authorization Required"

String including UTF-8 characters not working

I've got problems pushing Strings including special characters to our server. Special chars like "Ä" simply convert to "?" when pushing a mutation. Our server uses UTF-8 so the problem must occure on the serialization process of the client or something.

I'd like to include UTF-8, characters. Is there any fix to this? Thanks in advance.

Initial Introspection Fails: JsonReaderException

Context / What I Was Trying To Do:

I've been playing around with the Enjin Unity SDK (https://github.com/twglhk/Enjin-Unity-sample). The Enjin ecosystem uses GraphQL and, as you would expect, the Unity SDK is in large part centered around sending queries via web request to their graphql endpoints.

However, the SDK is kind of a mess. They are building a lot of their queries / injecting variables via string manipulation which is error prone and a security vulnerability. Given that, I have been exploring other, hopefully better options / tools for creating, serializing, sending, GraphQL queries (and receiving responses). This client looks awesome / like just what I need in many ways!

Unfortunately, I haven't been able to get it working yet!

The issue here / how to reproduce:

  1. I imported your plugin
  2. Created a new API Reference scriptable object (Named "Enjin API Reference)
  3. Added the URL to the endpoint (in this case, I am building out on the Kovan test network, the URL is "https://kovan.cloud.enjin.io/")
  4. Pressed "Introspect"
  5. The below errors / logs popped up and the scriptable object continues to say "API is being introspected, please wait..."

Any help would be greatly appreciated! Happy to provide more info if I missed something too!

Thanks for all of your hard work!
-Drake

Log That Gets Written Before the Unhandled Exception:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex,nofollow,noarchive" />
<title>An Error Occurred: Method Not Allowed</title>
<style>body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; }
.container { margin: 30px; max-width: 600px; }
h1 { color: #dc3545; font-size: 24px; }
h2 { font-size: 18px; }</style>
</head>
<body>
<div class="container">
<h1>Oops! An Error Occurred</h1>
<h2>The server returned a "405 Method Not Allowed".</h2>
<p>
Something is broken. Please let us know what you were doing when this error occurred.
We will fix it as soon as possible. Sorry for any inconvenience caused.
</p>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon='{"rayId":"6af15ca98d5319fb","token":"90b9898d975549fc99f35b663f8cf1e4","version":"2021.11.0","si":100}' crossorigin="anonymous"></script>
</body>
</html>
UnityEngine.Debug:Log (object)
GraphQlClient.Core.HttpHandler/<PostAsync>d__0:MoveNext () (at Assets/Plugins/graphQl-client/Scripts/Core/HttpHandler.cs:36)
System.Runtime.CompilerServices.AsyncMethodBuilderCore/MoveNextRunner:Run ()
GraphQlClient.Core.UnityWebRequestAwaiter:OnRequestCompleted (UnityEngine.AsyncOperation) (at Assets/Plugins/graphQl-client/Scripts/Extensions/UnityWebRequestExtensions.cs:30)
UnityEngine.AsyncOperation:InvokeCompletionEvent ()

Unhandled Exception:

JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
Newtonsoft.Json.JsonTextReader.ParseValue () (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonTextReader.Read () (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonReader.ReadAndMoveToContent () (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonReader.ReadForType (Newtonsoft.Json.Serialization.JsonContract contract, System.Boolean hasConverter) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value, Newtonsoft.Json.JsonSerializerSettings settings) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value) (at <bc3985d37b0241b48fc21474b2de25bd>:0)
GraphQlClient.Core.GraphApi.HandleIntrospection () (at Assets/Plugins/graphQl-client/Scripts/Core/GraphApi.cs:137)
UnityEditor.EditorApplication.Internal_CallUpdateFunctions () (at <2cd7ebc9c2ef4276a8edbc7de85c89ce>:0)

[WebGL] Json.SerializeObject returns empty string

Having struggled with exporting to WebGL, I've hit a roadblock with getting the .SetArgs function to work properly for adding arguments to both queries and mutations.
In editor, everything works fine, however when exporting to WebGL (with code stripping set to high) I've narrowed the debugging down to the string json = JsonConvert.SerializeObject(inputObject, new EnumInputConverter()); returning an empty string.

I suspect this is not strictly related to this repo but the newtonsoft library in general. However, it would be nice to get some insight.
I've tried using a link.xml and different "dont strip this" attributes to no avail. If anyone has an idea what is being stripped here that causes this behaviour, please let me know! (It works with stripping disabled)

Pokemon API getPokemon ENUM error

How to get a pokemon of 'givenName' using getPokemon method?

Query.getPokemon: Pokemon!
Gets details on a single Pokémon based on species name You can provide "takeFlavorTexts" to limit the amount of flavour texts to return, set the offset of where to start with "offsetFlavorTexts", and reverse the entire array with "reverseFlavorTexts". Reversal is applied before pagination!

Is there a way to pass arguments to subfields in the query?

for instance

query paginateProducts {
  site {
    products (first: 3) {
     (etc.)
          defaultImage{
            url(width: 200, height: 200)
          }
   }
}

passing args like this is pretty common in business oriented schema and I can't find info on doing this with this project.

Thanks

Subscription query issue

The subscription query throws error can't connect to the remote server while other queries are working properly. I am following the official tutorial from the following link.

I tried all possible ways including recreating the table, recreating a subscription query in the graph client but nothing worked! Subscription is working fine in the graphql editor but throws an error in Unity. I have attached an editor logs just for reference.

Screenshot 2020-10-06 195320

If you will need a project please let me know I will share it with you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.