├── APIGraphQL.cs ├── Coroutiner.cs ├── GraphQLClient.cs ├── GraphQLResponse.cs └── README.md /APIGraphQL.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GraphQL { 4 | public static class APIGraphQL { 5 | private const string ApiURL = "http://192.168.0.104:3000/graphql"; 6 | public static string Token = null; 7 | 8 | public static bool LoggedIn { 9 | get { return !Token.Equals(""); } //todo: improve loggedin verification 10 | } 11 | 12 | private static readonly GraphQLClient API = new GraphQLClient(ApiURL); 13 | 14 | public static void Query (string query, object variables = null, Action callback = null) { 15 | API.Query(query, variables, callback, Token); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Coroutiner.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. 3 | * 4 | * You are hereby granted a non-exclusive, worldwide, royalty-free license to use, 5 | * copy, modify, and distribute this software in source code or binary form for use 6 | * in connection with the web services and APIs provided by Facebook. 7 | * 8 | * As with any software that integrates with the Facebook platform, your use of 9 | * this software is subject to the Facebook Developer Principles and Policies 10 | * [http://developers.facebook.com/policy/]. This copyright notice shall be 11 | * included in all copies or substantial portions of the software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | */ 20 | 21 | using UnityEngine; 22 | using System.Collections; 23 | 24 | /// Convenience class that creates an ephemeral MonoBehaviour instance 25 | /// through which static classes can call StartCoroutine. 26 | public class Coroutiner { 27 | public static Coroutine StartCoroutine (IEnumerator iterationResult) { 28 | //Create GameObject with MonoBehaviour to handle task. 29 | GameObject routineHandlerGo = new GameObject("Coroutiner"); 30 | CoroutinerInstance routineHandler = 31 | routineHandlerGo.AddComponent(typeof(CoroutinerInstance)) as CoroutinerInstance; 32 | return routineHandler.ProcessWork(iterationResult); 33 | } 34 | } 35 | 36 | public class CoroutinerInstance : MonoBehaviour { 37 | void Awake () { 38 | DontDestroyOnLoad(this); 39 | } 40 | 41 | public Coroutine ProcessWork (IEnumerator iterationResult) { 42 | return StartCoroutine(DestroyWhenComplete(iterationResult)); 43 | } 44 | 45 | public IEnumerator DestroyWhenComplete (IEnumerator iterationResult) { 46 | yield return StartCoroutine(iterationResult); 47 | 48 | Destroy(gameObject); 49 | } 50 | } -------------------------------------------------------------------------------- /GraphQLClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Text; 4 | using Newtonsoft.Json; 5 | using UnityEngine.Networking; 6 | 7 | namespace GraphQL { 8 | public class GraphQLClient { 9 | private string url; 10 | 11 | public GraphQLClient (string url) { 12 | this.url = url; 13 | } 14 | 15 | private class GraphQLQuery { 16 | public string query; 17 | public object variables; 18 | } 19 | 20 | private UnityWebRequest QueryRequest (string query, object variables, string token = null) { 21 | var fullQuery = new GraphQLQuery() { 22 | query = query, 23 | variables = variables, 24 | }; 25 | 26 | string json = JsonConvert.SerializeObject(fullQuery); 27 | 28 | UnityWebRequest request = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST); 29 | 30 | byte[] payload = Encoding.UTF8.GetBytes(json); 31 | 32 | request.uploadHandler = new UploadHandlerRaw(payload); 33 | request.SetRequestHeader("Content-Type", "application/json"); 34 | if (token != null) request.SetRequestHeader("Authorization", "Bearer " + token); 35 | 36 | return request; 37 | } 38 | 39 | private IEnumerator SendRequest (string query, object variables = null, 40 | Action callback = null, 41 | string token = null) { 42 | var request = QueryRequest(query, variables, token); 43 | 44 | using (UnityWebRequest www = request) { 45 | yield return www.Send(); 46 | 47 | if (www.isNetworkError) { 48 | if (callback != null) callback(new GraphQLResponse("", www.error)); 49 | yield break; 50 | } 51 | 52 | string responseString = www.downloadHandler.text; 53 | 54 | var result = new GraphQLResponse(responseString); 55 | 56 | if (callback != null) callback(result); 57 | } 58 | 59 | request.Dispose(); 60 | } 61 | 62 | public void Query (string query, object variables = null, Action callback = null, 63 | string sToken = "") { 64 | Coroutiner.StartCoroutine(SendRequest(query, variables, callback, sToken)); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /GraphQLResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json.Linq; 3 | 4 | namespace GraphQL { 5 | public class GraphQLResponse { 6 | public string Raw { get; private set; } 7 | private readonly JObject data; 8 | public string Exception { get; private set; } 9 | 10 | public GraphQLResponse (string text, string ex = null) { 11 | Exception = ex; 12 | Raw = text; 13 | data = text != null ? JObject.Parse(text) : null; 14 | } 15 | 16 | public T Get (string key) { 17 | return GetData()[key].ToObject(); 18 | } 19 | 20 | public List GetList (string key) { 21 | return Get(key).ToObject>(); 22 | } 23 | 24 | private JObject GetData () { 25 | return data == null ? null : JObject.Parse(data["data"].ToString()); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GraphQL Client for Unity using UnityWebRequest 2 | 3 | Here is a sample client I made for a Unity app that utilizes a GraphQL api. 4 | I based my code on these sources: 5 | 6 | - [bkniffler/graphql-net-client](https://github.com/bkniffler/graphql-net-client) 7 | - [SaladLab/Json.Net.Unity3D (release 9.0.1)](https://github.com/SaladLab/Json.Net.Unity3D) 8 | - [carlflor/unity_graphql_client](https://github.com/carlflor/unity_graphql_client) 9 | - [Coroutiner from facebookarchive/friendsmash-unity](https://github.com/facebookarchive/friendsmash-unity/blob/master/friendsmash/Assets/Scripts/GameScripts/Coroutiner.cs) 10 | 11 | ### Configuration 12 | 13 | Set the GraphQL server URL at APIGraphQL.cs:5 14 | 15 | ### Sample Query & Mutation 16 | 17 | ``` c# 18 | 19 | public class SomeGameObject : MonoBehaviour { 20 | private class Credentials { 21 | public string email; 22 | public string password; 23 | } 24 | 25 | public InputField Email; 26 | public InputField Password; 27 | 28 | private Credentials GetCredentials => new Credentials { 29 | email = Email.text, 30 | password = Password.text 31 | }; 32 | 33 | string query = 34 | @"query ($input: Credentials!) { 35 | token: Login(credentials: $input) 36 | }"; 37 | 38 | string mutation = 39 | @"mutation ($input: Credentials!) { 40 | token: Register(credentials: $input) 41 | }"; 42 | 43 | void Login () { 44 | APIGraphQL.Query(query, new {input = GetCredentials}, callback); 45 | } 46 | 47 | void Register () { 48 | APIGraphQL.Query(mutation, new {input = GetCredentials}, callback); 49 | } 50 | 51 | private void callback (GraphQLResponse response) { 52 | string token = response.Get("token"); 53 | ... 54 | } 55 | 56 | ``` 57 | 58 | ### Example getting a list 59 | 60 | ``` c# 61 | public class Scores : MonoBehaviour { 62 | public class Score { 63 | public string name; 64 | public string score; 65 | } 66 | 67 | List scores; 68 | 69 | private string query = 70 | @"query ($top: Int) { 71 | scores: GetScores (top: $top) { 72 | name 73 | score 74 | } 75 | }"; 76 | 77 | private void Start () { 78 | APIGraphQL.Query(query, new {top = 10}, response => scores = response.GetList("scores")); 79 | } 80 | ``` 81 | 82 | *Issues are welcome! :)* 83 | --------------------------------------------------------------------------------