This HTTP/REST Client is based on Promises to avoid the Callback Hell ☠️ and the Pyramid of doom 💩 working with Coroutines in Unity 🎮, example:
varapi="https://jsonplaceholder.typicode.com";RestClient.GetArray<Post>(api+"/posts",(err,res)=>{RestClient.GetArray<Todo>(api+"/todos",(errTodos,resTodos)=>{RestClient.GetArray<User>(api+"/users",(errUsers,resUsers)=>{//Missing validations to catch errors!});});});But working with Promises we can improve our code, yay! 👏
RestClient.GetArray<Post>(api+"/posts").Then(response =>{EditorUtility.DisplayDialog("Success",JsonHelper.ArrayToJson<Post>(response,true),"Ok");returnRestClient.GetArray<Todo>(api+"/todos");}).Then(response =>{EditorUtility.DisplayDialog("Success",JsonHelper.ArrayToJson<Todo>(response,true),"Ok");returnRestClient.GetArray<User>(api+"/users");}).Then(response =>{EditorUtility.DisplayDialog("Success",JsonHelper.ArrayToJson<User>(response,true),"Ok");}).Catch(err =>EditorUtility.DisplayDialog("Error",err.Message,"Ok"));- Works out of the box 🎉
- Make HTTP requests from Unity
- Supports HTTPS/SSL
- Built on top of UnityWebRequest system
- Transform request and response data (JSON serialization with JsonUtility or other tools)
- Automatic transforms for JSON Arrays.
- Supports default HTTP Methods (GET, POST, PUT, DELETE, HEAD, PATCH)
- Generic REQUEST method to create any http request
- Based on Promises for a better asynchronous programming. Learn about Promises here!
- Utility to work during scene transition
- Handle HTTP exceptions and retry requests easily
- Open Source 🦄
The UnityWebRequest system supports most Unity platforms:
- All versions of the Editor and Standalone players
- WebGL
- Mobile platforms: iOS, Android
- Universal Windows Platform
- PS4 and PSVita
- XboxOne
- HoloLens
- Nintendo Switch
Do you want to see this beautiful package in action? Download the demo here
Download and install the .unitypackage file of the latest release published here.
Make sure you had installed C# Promise package or at least have it in your openupm scope registry. Then install RestClient package using this URL from Package Manager: https://github.com/proyecto26/RestClient.git#upm
Other option is download this package from NuGet with Visual Studio or using the nuget-cli, a NuGet.config file is required at the root of your Unity Project, for example:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<addkey="repositoryPath"value="./Assets/Packages" />
</config>
</configuration>The package to search for is Proyecto26.RestClient.
The default methods (GET, POST, PUT, DELETE, HEAD) are:
RestClient.Get("https://jsonplaceholder.typicode.com/posts/1").Then(response =>{EditorUtility.DisplayDialog("Response",response.Text,"Ok");});RestClient.Post("https://jsonplaceholder.typicode.com/posts",newPost).Then(response =>{EditorUtility.DisplayDialog("Status",response.StatusCode.ToString(),"Ok");});RestClient.Put("https://jsonplaceholder.typicode.com/posts/1",updatedPost).Then(response =>{EditorUtility.DisplayDialog("Status",response.StatusCode.ToString(),"Ok");});RestClient.Delete("https://jsonplaceholder.typicode.com/posts/1").Then(response =>{EditorUtility.DisplayDialog("Status",response.StatusCode.ToString(),"Ok");});RestClient.Head("https://jsonplaceholder.typicode.com/posts").Then(response =>{EditorUtility.DisplayDialog("Status",response.StatusCode.ToString(),"Ok");});ExecuteOnMainThread.RunOnMainThread.Enqueue(()=>{//Any API call using RestClient});And we have a generic method to create any type of request:
RestClient.Request(newRequestHelper{Uri="https://jsonplaceholder.typicode.com/photos",Method="POST",Timeout=10,Params=newDictionary<string,string>{{"param1","Query string param..."}},Headers=newDictionary<string,string>{{"Authorization","Bearer JWT_token..."}},Body=newPhoto,//Serialize object using JsonUtility by defaultBodyString=SerializeObject(newPhoto),//Use it instead of 'Body' to serialize using other toolsBodyRaw=CompressToRawData(newPhoto),//Use it instead of 'Body' to send raw data directlyFormData=newWWWForm(),//Send files, etc with POST requestsSimpleForm=newDictionary<string,string>{},//Content-Type: application/x-www-form-urlencodedFormSections=newList<IMultipartFormSection>(){},//Content-Type: multipart/form-dataCertificateHandler=newCustomCertificateHandler(),//Create custom certificatesUploadHandler=newUploadHandlerRaw(bytes),//Send bytes directly if it's requiredDownloadHandler=newDownloadHandlerFile(destPah),//Download large filesContentType="application/json",//JSON is used by defaultRetries=3,//Number of retriesRetrySecondsDelay=2,//Seconds of delay to make a retryRetryCallbackOnlyOnNetworkErrors=true,//Invoke RetryCallack only when the retry is provoked by a network errorRetryCallback=(err,retries)=>{},//See the error before retrying the requestProgressCallback=(percent)=>{},//Reports progress of the request from 0 to 1EnableDebug=true,//See logs of the requests for debug modeIgnoreHttpException=true,//Prevent to catch http exceptionsChunkedTransfer=false,UseHttpContinue=true,RedirectLimit=32,DefaultContentType=false,//Disable JSON content type by defaultParseResponseBody=false//Don't encode and parse downloaded data as JSON}).Then(response =>{//Get resources via downloadHandler to get more control!Texturetexture=((DownloadHandlerTexture)response.Request.downloadHandler).texture;AudioClipaudioClip=((DownloadHandlerAudioClip)response.Request.downloadHandler).audioClip;AssetBundleassetBundle=((DownloadHandlerAssetBundle)response.Request.downloadHandler).assetBundle;EditorUtility.DisplayDialog("Status",response.StatusCode.ToString(),"Ok");}).Catch(err =>{varerror=errasRequestException;EditorUtility.DisplayDialog("Error Response",error.Response,"Ok");});- Example downloading an audio file:
varfileUrl="https://raw.githubusercontent.com/IonDen/ion.sound/master/sounds/bell_ring.ogg";varfileType=AudioType.OGGVORBIS;RestClient.Get(newRequestHelper{Uri=fileUrl,DownloadHandler=newDownloadHandlerAudioClip(fileUrl,fileType)}).Then(res =>{AudioSourceaudio=GetComponent<AudioSource>();audio.clip=((DownloadHandlerAudioClip)res.Request.downloadHandler).audioClip;audio.Play();}).Catch(err =>{EditorUtility.DisplayDialog("Error",err.Message,"Ok");});With all the methods we have the possibility to indicate the type of response, in the following example we're going to create a class and the HTTP requests to load JSON data easily:
[Serializable]publicclassUser{publicintid;publicstringname;publicstringusername;publicstringemail;publicstringphone;publicstringwebsite;}- GET JSON
varusersRoute="https://jsonplaceholder.typicode.com/users";RestClient.Get<User>(usersRoute+"/1").Then(firstUser =>{EditorUtility.DisplayDialog("JSON",JsonUtility.ToJson(firstUser,true),"Ok");});- GET Array (JsonHelper is an extension to manage arrays)
RestClient.GetArray<User>(usersRoute).Then(allUsers =>{EditorUtility.DisplayDialog("JSON Array",JsonHelper.ArrayToJsonString<User>(allUsers,true),"Ok");});Also we can create different classes for custom responses:
[Serializable]publicclassCustomResponse{publicintid;}- POST
RestClient.Post<CustomResponse>(usersRoute,newUser).Then(customResponse =>{EditorUtility.DisplayDialog("JSON",JsonUtility.ToJson(customResponse,true),"Ok");});- PUT
RestClient.Put<CustomResponse>(usersRoute+"/1",updatedUser).Then(customResponse =>{EditorUtility.DisplayDialog("JSON",JsonUtility.ToJson(customResponse,true),"Ok");});HTTP Headers, such as Authorization, can be set in the DefaultRequestHeaders object for all requests
RestClient.DefaultRequestHeaders["Authorization"]="Bearer ...";Query string params can be set in the DefaultRequestParams object for all requests
RestClient.DefaultRequestParams["param1"]="Query string value...";Also we can add specific options and override default headers and params for a request
varcurrentRequest=newRequestHelper{Uri="https://jsonplaceholder.typicode.com/photos",Headers=newDictionary<string,string>{{"Authorization","Other token..."}},Params=newDictionary<string,string>{{"param1","Other value..."}}};RestClient.GetArray<Photo>(currentRequest).Then(response =>{EditorUtility.DisplayDialog("Header",currentRequest.GetHeader("Authorization"),"Ok");});And we can know the status of the request and cancel it!
currentRequest.UploadProgress;//The progress by uploading data to the servercurrentRequest.UploadedBytes;//The number of bytes of body data the system has uploadedcurrentRequest.DownloadProgress;//The progress by downloading data from the servercurrentRequest.DownloadedBytes;//The number of bytes of body data the system has downloadedcurrentRequest.Abort();//Abort the request manuallyAdditionally we can run a callback function whenever a progress change happens!
RestClient.Get(newRequestHelper{Uri="https://jsonplaceholder.typicode.com/users",ProgressCallback= percent =>Debug.Log(percent)});Later we can clear the default headers and params for all requests
RestClient.ClearDefaultHeaders();RestClient.ClearDefaultParams();- Unity as Client
[Serializable]publicclassServerResponse{publicstringid;publicstringdate;//DateTime is not supported by JsonUtility}[Serializable]publicclassUser{publicstringfirstName;publicstringlastName;}RestClient.Post<ServerResponse>("www.api.com/endpoint",newUser{firstName="Juan David",lastName="Nicholls Cardona"}).Then(response =>{EditorUtility.DisplayDialog("ID: ",response.id,"Ok");EditorUtility.DisplayDialog("Date: ",response.date,"Ok");});- NodeJS as Backend (Using Express)
router.post('/',function(req,res){console.log(req.body.firstName)res.json({id: 123,date: newDate()})});This project is free and open source. Sponsors help keep it maintained and growing.
Become a Sponsor | Sponsorship Program
When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated ❤️.
You can learn more about how you can contribute to this project in the contribution guide.
Please do contribute! Issues and pull requests are welcome.
This project exists thanks to all the people who contribute. [Contribute].
| Juan Nicholls | Diego Ossa | Nasdull | Maifee Ul Asad |
Available as part of the Tidelift Subscription.
The maintainers of RestClient for Unity and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.
To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.
We are battle tested. There is a list of our usage in production:
- mainware. Ref: #138 (comment)
- virsabi. Ref: #138 (comment)
- type3studio. Ref: #138 (comment)
This repository is available under the MIT License.
- C-Sharp-Promise:Promises library for C# for management of asynchronous operations.
- MyAPI:A template to create awesome APIs easily ⚡️
Made with ❤️ by Proyecto 26


