Git Product home page Git Product logo

simplegraphql-for-unity's Introduction

Hello there! Computers are fascinating things, aren't they?

Navid's GitHub stats

simplegraphql-for-unity's People

Contributors

johanhelsing avatar navidk0 avatar psoudanlemon avatar sewdn avatar skjalgsm-statespace 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

Watchers

 avatar  avatar  avatar  avatar

simplegraphql-for-unity's Issues

Anonymous type resolver doesn't seem to work on WebGL

I guess I was a bit quick with one of those PRs as it doesn't seem to work on WebGL. I get errors like this in the console

JsonSerializationException: Unable to find a constructor to use for type SimpleGraphQL.Response`1[<>f__AnonymousType4`1[<>f__AnonymousType2`1[System.String]]]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'data', line 1, position 8.
  at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract objectContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, Newtonsoft.Json.Serialization.JsonProperty containerProperty, System.String id, System.Boolean& createdFromNonDefaultCreator) [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0

I think it's related to code stripping. Although elegant, perhaps the lambda resolver method doesn't quite work with il2cpp builds.

Looking into workarounds.

Or maybe I just need to add an empty constructor somewhere and put some attribute on it. Will investigate further tomorrow.

Can WebGL be fully supported?

Hi, this is a really cool project! I was considering doing something similar myself/forking the "graphQL-client-unity" project because I didn't like how it hides too much behind its gui in scriptable objects, and I also wanted something that was a Unity package. This project seems like a really good start.

Now, I mainly develop for WebGL, though. So it would be good to clarify exactly what works, and what doesn't.

This should work with all platforms (Mono/IL2CPP) except for WebGL, since Unity WebGL has issues with threading. If you are using WebGL, this package may be hit-or-miss for you at the present time. It makes use of UnityWebRequest where possible, but the WebSockets are the main issue, so subscriptions may not properly work. If you do not need subscriptions, WebGL may work just fine.

Specifically, the "may or may not" without WebSockets part may be good to clarify.

I think some parts of the Task API may be problematic on WebGL, but I don't know enough about it to say whether the parts used here are safe for WebGL or not, but in any case most of it should be possible to fix by using UniTask instead, in any case that's what I normally use myself to be on the safe side.

It would also be cool to check if the solution proposed here is enough to be able to support subscriptions on WebGL as well.

I'll do some prototyping, just wanted to say hi and hear your thoughts on:

  • Adding CySharp.UniTask as a dependency if there are issues with Task on WebGL
  • Alternatively adding CySharp.UniTask as an optional dependency and have ifdefs to alias to it installed.
  • Add some jslib helper code to support subscriptions

No support for arrays in GraphQL Input types?

Hi,

I get this exception from GraphQLParser/ParserContext.cs:147

GraphQLSyntaxErrorException: Syntax Error GraphQL (1:25) Expected $, found [
1: query Games($gameIds: ID[]!) {
                           ^

I'm guessing there is currently no support for this graphql syntax: (although it is valid syntax and it works against my running and validated schema):

query Games($gameIds: [ID!]!) {
  games(gameIds: $gameIds) {
    _id
    ...
  }
}

Is the Parser a port of an existing GraphQL parser implementation?

How to use the SendAsync with coroutine

In the readme it says that the library is usable with coroutines with callback, would you mind adding an example on how to achieve this for those amongst us with less in depth C# knowledge?

Also, is there a advantage of using coroutines over async/await? I read in the Unity manual that using async/await is discouraged, but don't know how or if this applies to this situation?

GraphQLConfig Files list doesn't accept .graphql files

I have a bunch of graphql files I'd like to use, but I cant drag them into the Files field in the GraphQLConfig.

When looking at the code, those files are actually ScriptableObjects which I can't create as they lack the appropriate menu item for it. How do I proceed?

Improve documentation

Documentation could use some improvement to showcase how to use the Request API vs the Query API (aka GraphQL from files). Some small examples would probably be enough.

Change from using GUID to copying link.xml directly into project?

From #15, which was merged, but my last post still stands. It could be a solution that doesn't require intervention if the GUID changes within the package.

I see, hmm. Using the GUID feels quite fragile, I must admit. I wonder if there's a better way just using a relative path directly to the link.xml file and then providing the full path from there? We could just stick it inside our project, copy it to their project in Plugins/SimpleGraphQL before build using a IPreprocessBuildWithReport.OnPreprocessBuild? (We could also do it on install when assets are being imported.)

Problems when subscriptions complete

Hi,

I was encountering issues when using multiple subscriptions in my application (using graphql-transport-ws subProtocol).
SimpleGraphQLClient is (by design) using a single Websocket instance for all running subscriptions.

However, when a running subscription is unsubscribed (the graphql server will handle this request with a stop/complete payload), the WebSocketUpdate breaks (https://github.com/LastAbyss/SimpleGraphQL-For-Unity/blob/master/Runtime/SimpleGraphQL/HttpUtils.cs#L368), and no further payloads are being processed anymore, so other subscriptions don't receive any updates.

I suggest to just continue the loop, when a subscription completes/ends. Or would this harm performance?
Another suggestion is to track the running subscriptions, and disconnect (dispose) the single web socket as soon as all subscriptions where unsubscribed again. When opening a new subscription afterwards, this would reopen a new connection, and restart the update cycle.

What do you think?

Question, handling different response Types

            var client = new GraphQLClient("xxx/api/graphql", null, headers, null);
            var request = new Request
            {
                Query = "query FindAccount($userId: Long!) { findAccount(userId: $userId) { " 
                        +"... on Account { id, type, userId, email, expirationDate, lastSubscriptionReminderDate, isDeveloper }"
                        +"... on NotFound { notFound }" 
                        +"... on BadRequestError { type, message }" 
                        +"... on AppError { type, message} } }",
                    Variables = new
                {
                    userId= this.userId().Value()
                }
            };
            var responseType = new { findAccount = new { type ="" , message =""} } ;
            var response = await client.Send( () => responseType, request);

How do I properly work on query that can return multiple response Types?

Thanks in advance
Fer

A Native Collection has not been disposed, resulting in a memory leak. Allocated from: Unity.Collections.NativeArray

You have to dispose the UnityWebRequest and its UploadHandler and Downloadhandler when its not in use any more.

The reason why you are not seeing this error (but will still experience leaking and memory build up) is because UnityWebRequest is using NativeArray, but the warnings associated with it can just be turned on (and off again) if you install the Burst package into your project. So its a good tip to install that, then turn on the debugging, and uninstall it again. That way you will always see this error when you forget to Dispose.

A Native Collection has not been disposed, resulting in a memory leak. Allocated from:
Unity.Collections.NativeArray`1:.ctor(Byte[], Allocator)
UnityEngine.Networking.UploadHandlerRaw:.ctor(Byte[])
SimpleGraphQL.<PostRequestAsync>d__5:MoveNext() (at D:\statespacelabs\Packages\SimpleGraphQL-For-Unity\Runtime\SimpleGraphQL\HttpUtils.cs:53)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start(<PostRequestAsync>d__5&)
SimpleGraphQL.HttpUtils:PostRequestAsync(String, Request, Dictionary`2, String, String)
SimpleGraphQL.<Send>d__6:MoveNext() (at D:\statespacelabs\Packages\SimpleGraphQL-For-Unity\Runtime\SimpleGraphQL\GraphQLClient.cs:76)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start(<Send>d__6&)
SimpleGraphQL.GraphQLClient:Send(Request, Dictionary`2, String, String)
SimpleGraphQL.<Send>d__7`1:MoveNext() (at D:\statespacelabs\Packages\SimpleGraphQL-For-Unity\Runtime\SimpleGraphQL\GraphQLClient.cs:94)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start(<Send>d__7`1&)
SimpleGraphQL.GraphQLClient:Send(Request, Dictionary`2, String, String)
AimLab.GraphQL.<QueryInternal>d__15`1:MoveNext() (at Assets\Runtime\GraphQLUtility.cs:162)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start(<QueryInternal>d__15`1&)
AimLab.GraphQL.GraphQLUtility:QueryInternal(GraphQLConfig, AccessTokenResponse, String, OperationType, Object, Int32)
AimLab.GraphQL.<Query>d__14`1:MoveNext() (at Assets\Runtime\GraphQLUtility.cs:147)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start(<Query>d__14`1&)
AimLab.GraphQL.GraphQLUtility:Query(AccessTokenResponse, String, OperationType, Object)

Can't seem to pass variables

Hi,
I've been trying out the library and I've had mixed successes.
Queries without any variables work, including the ones that require JWT authorisation, which is awesome!

I can't get mutations to work however. Keep getting backend errors that the variables are not provided.
Graphql document:

mutation loginWithPassword($email:String! $password: String!) 
{
  loginWithPassword(email: $email, password: $password) {
    tokens {
      accessToken
    },
    user {
      profile {
        fullName
      }
    }
  }
}

Code to send the mutation:

public async void PostLogin(string email, string password)
  {
    var graphQL = new GraphQLClient(Config);

    Query loginMutation = graphQL.FindQuery("Login");
    string results = await graphQL.SendAsync(
        loginMutation,
        "jwt",
        null,
        new Dictionary<string, string>
        {
                {"$email", email},
                {"$password", password}
        }
    );
    Debug.Log(results);
  }

Stacktrace:
{"errors":[{"message":"Variable \"$email\" of required type \"String!\" was not provided.","locations":[{"line":1,"column":28}],"extensions":{"code":"INTERNAL_SERVER_ERROR","exception":{"stacktrace":["GraphQLError: Variable \"$email\" of required type \"String!\" was not provided."," at _loop (/app/node_modules/graphql/execution/values.js:94:17)"," at coerceVariableValues (/app/node_modules/graphql/execution/values.js:121:16)"," at getVariableValues (/app/node_modules/graphql/execution/values.js:50:19)"," at buildExecutionContext (/app/node_modules/graphql/execution/execute.js:206:61)"," at executeImpl (/app/node_modules/graphql/execution/execute.js:104:20)"," at Object.execute (/app/node_modules/graphql/execution/execute.js:63:35)"," at /app/node_modules/apollo-server-core/src/requestPipeline.ts:545:22"," at Generator.next (<anonymous>)"," at /app/node_modules/apollo-server-core/dist/requestPipeline.js:8:71"," at new Promise (<anonymous>)"]}}},{"message":"Variable \"$password\" of required type \"String!\" was not provided.","locations":[{"line":1,"column":43}],"extensions":{"code":"INTERNAL_SERVER_ERROR","exception":{"stacktrace":["GraphQLError: Variable \"$password\" of required type \"String!\" was not provided."," at _loop (/app/node_modules/graphql/execution/values.js:94:17)"," at coerceVariableValues (/app/node_modules/graphql/execution/values.js:121:16)"," at getVariableValues (/app/node_modules/graphql/execution/values.js:50:19)"," at buildExecutionContext (/app/node_modules/graphql/execution/execute.js:206:61)"," at executeImpl (/app/node_modules/graphql/execution/execute.js:104:20)"," at Object.execute (/app/node_modules/graphql/execution/execute.js:63:35)"," at /app/node_modules/apollo-server-core/src/requestPipeline.ts:545:22"," at Generator.next (<anonymous>)"," at /app/node_modules/apollo-server-core/dist/requestPipeline.js:8:71"," at new Promise (<anonymous>)"]}}}]}

I've verified the mutation in graphql playground and it's definitely correctly formed. Also tried putting in hardcoded variables and writing the variable keys without $.

Am I missing something? I'm pretty new to C#, so might just be that I'm making a mistake somewhere....

Closing Subscriptions to Websocket

I have multiple subscription open within a mobile game I am developing. I was wandering If there is any way to unsubscribe from all active subscriptions and unregister all their listeners in order to safely reload my game.

Add a contributing.md

@NavidK0 Just wondering how you prefer things to be done?

Things like:

  • Is breaking changes ok (bumping major version of course)? Or do you prefer to avoid this as much as possible?
  • Now that I get write access, do you still prefer changes to go through PRs?
  • Other things?

Might make sense to put this in a contributing.md.

IL2CPP Build Issue

Hi, I have an app that uses this simple graphql package. The package seems to be working perfectly on Mono on both unity editor and android device but when i switch to scripting backend il2cpp I can only see the data on the editor but not on the android device.

Headers not working in subscriptions with aws appsync

Hello,

Nice work on the graphql queries and mutations.

Everything seems very easy to understand

I noticed when I add a header dictionary to the field to Subscribe like so:

bool success = await graphQL.Subscribe(
query.ToRequest(),
new Dictionary<string, string>
{
{"header", "headerSerializedCorrectly"},
{"payload", "e30="},
}
);

The response from the server is the header and payload fields are missing in the header.

I followed the structure of AppSync to the Tee: https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html

Query -> Request issue

Hello! I'm trying to use this package to make graphql requests but when I try to follow the example code to send a request, it throws an error about it can't convert a query to a request. I would appreciate some guidance on this, thank you!

Old projects not compiling after upgrading minor version

After upgrading, my project stopped working due to this change:

b4a473b

The code that stopped building

            var result = await apiClient.Send(
                () => new { result = resultTypeResolver() },
                request,
                null,
                token,
                scheme);
            var result = await apiClient.Send(
                () => new { result = resultTypeResolver() },
                request,
                null, // <-- needed to add this argument after upgrading to latest version
                null,
                token,
                scheme);

We should probably either bump major version or restore an overload with the old api, or move the settings arg so it's the last overload.

Doesn't build on Unity 2019.4

Complains about ScriptedImporter is missing.

Sorry, upgraded the repo to 2020.3 (where it builds fine) already, so I don't have the full error, just thought I'd flag it.

Still issues with code stripping on WebGL

I submitted a fix for a webgl stripping issue earlier, but it turns out it wasn't enough.

There are no errors. The deserialized responses that are returned have no errors, but the Response.Data field is also null even though I can see that there is data in the response body in the browser inspector. The code that accesses stuff inside the Data field, i.e. Response.Data.gameSession.id also happily converts to null, so I didn't really get any errors for these things, which is why I didn't notice earlier.

I managed to make it work by adding a link.xml file to disable stripping

<linker>
    <assembly fullname="LastAbyss.SimpleGraphQL.Runtime" preserve="all" />
    <assembly fullname="AssemblyCSharp" preserve="all" />
</linker>

However, it also increased build size quite badly... I'll do some more tests and see if I can be more specific.

I guess we should either remove the anonymous api again or add a big fat warning to the readme?

error CS0539: 'LinkXmlInjector.OnBeforeRun(BuildReport, UnityLinkerBuildPipelineData)' in explicit interface declaration is not found among members of the interface that can be implemented

Thank you for the wonderful library.

Unity 2021.2.0b13 (macOS)

error CS0539: 'LinkXmlInjector.OnBeforeRun(BuildReport, UnityLinkerBuildPipelineData)' in explicit interface declaration is not found among members of the interface that can be implemented

/Editor/LinkXmlInjector.cs

        void IUnityLinkerProcessor.OnBeforeRun(BuildReport report, UnityLinkerBuildPipelineData data)
        {
        }

        void IUnityLinkerProcessor.OnAfterRun(BuildReport report, UnityLinkerBuildPipelineData data)
        {
        }

https://unity3d.com/jp/unity/whats-new/2021.1.0

  • Scripting: Deprecated: Deprecated IUnityLinkerProcessor.OnAfterRun.
  • Scripting: Deprecated: Deprecated IUnityLinkerProcessor.OnBeforeRun.

definition for 'Result' and no accessible extension method 'Result' accepting a first argument of type 'Response<<anonymous type:

Hi !
I'm trying to make a simple graphql query, supposed to return an array of integers. I've replaced my query and the value in the example. Nevertheless i'm getting the following error when trying to access response.Result :

Response<<anonymous type: <anonymous type: string tokenId>[] tokens>>' does not contain a definition for 'Result' and no accessible extension method 'Result' accepting a first argument of type 'Response<<anonymous type: <anonymous type: string tokenId>[] tokens>>' could be found (are you missing a using directive or an assembly reference?)

The return from the query is { owner: { tokens: Array<{ tokenID }> } }

Screenshot 2022-12-31 at 13 59 30

The query is supposed to return an array of integers, is it giving me that error because of the return type?

Thanks a lot <3

Slower Calls After Update

Hi, I have been using SimpleGraphQL package for one of the games I am developing and recently when I update to the latest version I noticed a bit of a lag when making requests. Not sure where the problem is but the lag is noticeable. The package version I was using before is 1.1.3 and I have updated to version 1.2.0.

API hides cause of http errors

It's currently hard to do proper error handling with this library.

Normal GraphQL error responses from the server are more or less fine, the response object will have an Errors field, which can be checked.

However, if something else fails when calling GraphQLClient.Send that is not a GraphQL error response, the method will simply return null or an empty string.

This is because HttpUtils.PostRequestAsync returns webRequest.downloadHandler.text without checking for or passing on webRequest.error or webRequest.result.

This means the following logic can't currently be implemented:

if (connection error)
  wait and try again
if (http 401 unauthorized)
  log in and try again
if (http 404 etc)
  give up

One quite simple solution might be to throw exceptions that wrap the UnityWebRequest.

Personally, I would prefer not throwing and instead return something like rust's Result types, so it's obvious that something can fail and that you'd have to handle errors. However it looks like we'd have to wait for C# 9 enum class support in Unity to implement this in a clean way.

@NavidK0 Perhaps it's better to go with a simple stupid approach and add a UnityWebRequestException class to the API? Then we could change it later?

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.