Skip to content

Commit ccfcb12

Browse files
committed
Implemented Promise requests using PromiseYielder instead of Coroutines.
Replaced RSG with ProtoPromise in demo. Updated readme.
1 parent 14af97e commit ccfcb12

28 files changed

+9043
-255
lines changed

README.md

+34-26
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,22 @@ RestClient.GetArray<Post>(api + "/posts", (err, res) => {
3131
But working with **Promises** we can improve our code, yay! 👏
3232

3333
```csharp
34-
RestClient.GetArray<Post>(api + "/posts").Then(response => {
35-
EditorUtility.DisplayDialog ("Success", JsonHelper.ArrayToJson<Post>(response, true), "Ok");
36-
return RestClient.GetArray<Todo>(api + "/todos");
37-
}).Then(response => {
38-
EditorUtility.DisplayDialog ("Success", JsonHelper.ArrayToJson<Todo>(response, true), "Ok");
39-
return RestClient.GetArray<User>(api + "/users");
40-
}).Then(response => {
41-
EditorUtility.DisplayDialog ("Success", JsonHelper.ArrayToJson<User>(response, true), "Ok");
42-
}).Catch(err => EditorUtility.DisplayDialog ("Error", err.Message, "Ok"));
34+
RestClient.GetArray<Post>(api + "/posts")
35+
.Then(response =>
36+
{
37+
EditorUtility.DisplayDialog ("Success", JsonHelper.ArrayToJson<Post>(response, true), "Ok");
38+
return RestClient.GetArray<Todo>(api + "/todos");
39+
})
40+
.Then(response =>
41+
{
42+
EditorUtility.DisplayDialog ("Success", JsonHelper.ArrayToJson<Todo>(response, true), "Ok");
43+
return RestClient.GetArray<User>(api + "/users");
44+
})
45+
.Then(response => {
46+
EditorUtility.DisplayDialog ("Success", JsonHelper.ArrayToJson<User>(response, true), "Ok");
47+
})
48+
.Catch((RequestException err) => EditorUtility.DisplayDialog ("Error", err.Message, "Ok"))
49+
.Forget();
4350
```
4451

4552
## Features 🎮
@@ -51,7 +58,7 @@ RestClient.GetArray<Post>(api + "/posts").Then(response => {
5158
- Automatic transforms for **JSON Arrays**.
5259
- Supports default **HTTP** Methods **(GET, POST, PUT, DELETE, HEAD, PATCH)**
5360
- Generic **REQUEST** method to create any http request
54-
- Based on **Promises** for a better asynchronous programming. Learn about Promises [here](https://github.com/Real-Serious-Games/C-Sharp-Promise)!
61+
- Based on **Promises** for a better asynchronous programming. Learn about Promises [here](https://github.com/timcassell/ProtoPromise)!
5562
- Utility to work during scene transition
5663
- Handle HTTP exceptions and retry requests easily
5764
- Open Source 🦄
@@ -80,7 +87,7 @@ Do you want to see this beautiful package in action? Download the demo [here](ht
8087
Download and install the **.unitypackage** file of the latest release published [here](https://github.com/proyecto26/RestClient/releases).
8188

8289
### UPM package
83-
Make sure you had installed [C# Promise package](https://openupm.com/packages/com.rsg.promise/) or at least have it in your [openupm scope registry](https://openupm.com/). Then install **RestClient package** using this URL from **Package Manager**: `https://github.com/proyecto26/RestClient.git#upm`
90+
Make sure you had installed [ProtoPromise package](https://openupm.com/packages/com.timcassell.protopromise/) or at least have it in your [openupm scope registry](https://openupm.com/). Then install **RestClient package** using this URL from **Package Manager**: `https://github.com/proyecto26/RestClient.git#upm`
8491

8592
### NuGet package
8693
Other option is download this package from **NuGet** with **Visual Studio** or using the **nuget-cli**, a **[NuGet.config](https://github.com/proyecto26/RestClient/blob/master/demo/NuGet.config)** file is required at the root of your **Unity Project**, for example:
@@ -100,19 +107,19 @@ The default methods **(GET, POST, PUT, DELETE, HEAD)** are:
100107
```csharp
101108
RestClient.Get("https://jsonplaceholder.typicode.com/posts/1").Then(response => {
102109
EditorUtility.DisplayDialog("Response", response.Text, "Ok");
103-
});
110+
}).Forget();
104111
RestClient.Post("https://jsonplaceholder.typicode.com/posts", newPost).Then(response => {
105112
EditorUtility.DisplayDialog("Status", response.StatusCode.ToString(), "Ok");
106-
});
113+
}).Forget();
107114
RestClient.Put("https://jsonplaceholder.typicode.com/posts/1", updatedPost).Then(response => {
108115
EditorUtility.DisplayDialog("Status", response.StatusCode.ToString(), "Ok");
109-
});
116+
}).Forget();
110117
RestClient.Delete("https://jsonplaceholder.typicode.com/posts/1").Then(response => {
111118
EditorUtility.DisplayDialog("Status", response.StatusCode.ToString(), "Ok");
112-
});
119+
}).Forget();
113120
RestClient.Head("https://jsonplaceholder.typicode.com/posts").Then(response => {
114121
EditorUtility.DisplayDialog("Status", response.StatusCode.ToString(), "Ok");
115-
});
122+
}).Forget();
116123
```
117124

118125
## Handling during scene transition
@@ -164,10 +171,10 @@ RestClient.Request(new RequestHelper {
164171
AssetBundle assetBundle = ((DownloadHandlerAssetBundle)response.Request.downloadHandler).assetBundle;
165172

166173
EditorUtility.DisplayDialog("Status", response.StatusCode.ToString(), "Ok");
167-
}).Catch(err => {
174+
}).Catch((RequestException err) => {
168175
var error = err as RequestException;
169176
EditorUtility.DisplayDialog("Error Response", error.Response, "Ok");
170-
});
177+
}).Forget();
171178
```
172179

173180
- Example downloading an audio file:
@@ -182,9 +189,9 @@ RestClient.Get(new RequestHelper {
182189
AudioSource audio = GetComponent<AudioSource>();
183190
audio.clip = ((DownloadHandlerAudioClip)res.Request.downloadHandler).audioClip;
184191
audio.Play();
185-
}).Catch(err => {
192+
}).Catch((RequestException err) => {
186193
EditorUtility.DisplayDialog ("Error", err.Message, "Ok");
187-
});
194+
}).Forget();
188195
```
189196

190197
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:
@@ -206,13 +213,13 @@ public class User
206213
var usersRoute = "https://jsonplaceholder.typicode.com/users";
207214
RestClient.Get<User>(usersRoute + "/1").Then(firstUser => {
208215
EditorUtility.DisplayDialog("JSON", JsonUtility.ToJson(firstUser, true), "Ok");
209-
});
216+
}).Forget();
210217
```
211218
* **GET Array (JsonHelper is an extension to manage arrays)**
212219
```csharp
213220
RestClient.GetArray<User>(usersRoute).Then(allUsers => {
214221
EditorUtility.DisplayDialog("JSON Array", JsonHelper.ArrayToJsonString<User>(allUsers, true), "Ok");
215-
});
222+
}).Forget();
216223
```
217224

218225
Also we can create different classes for custom responses:
@@ -227,13 +234,13 @@ public class CustomResponse
227234
```csharp
228235
RestClient.Post<CustomResponse>(usersRoute, newUser).Then(customResponse => {
229236
EditorUtility.DisplayDialog("JSON", JsonUtility.ToJson(customResponse, true), "Ok");
230-
});
237+
}).Forget();
231238
```
232239
* **PUT**
233240
```csharp
234241
RestClient.Put<CustomResponse>(usersRoute + "/1", updatedUser).Then(customResponse => {
235242
EditorUtility.DisplayDialog("JSON", JsonUtility.ToJson(customResponse, true), "Ok");
236-
});
243+
}).Forget();
237244
```
238245

239246
## Custom HTTP Headers, Params and Options 💥
@@ -260,7 +267,7 @@ var currentRequest = new RequestHelper {
260267
};
261268
RestClient.GetArray<Photo>(currentRequest).Then(response => {
262269
EditorUtility.DisplayDialog("Header", currentRequest.GetHeader("Authorization"), "Ok");
263-
});
270+
}).Forget();
264271
```
265272

266273
And we can know the status of the request and cancel it!
@@ -305,7 +312,7 @@ RestClient.Post<ServerResponse>("www.api.com/endpoint", new User {
305312
}).Then(response => {
306313
EditorUtility.DisplayDialog("ID: ", response.id, "Ok");
307314
EditorUtility.DisplayDialog("Date: ", response.date, "Ok");
308-
});
315+
}).Forget();
309316
```
310317
- NodeJS as Backend (Using [Express](http://expressjs.com/es/starter/hello-world.html))
311318
```js
@@ -319,6 +326,7 @@ router.post('/', function(req, res) {
319326
```
320327

321328
## Credits 👍
329+
* **ProtoPromise** [Robust and efficient library for management of asynchronous operations.](https://github.com/timcassell/ProtoPromise)
322330
* **C-Sharp-Promise:** [Promises library for C# for management of asynchronous operations.](https://github.com/Real-Serious-Games/C-Sharp-Promise)
323331
* **MyAPI:** [A template to create awesome APIs easily ⚡️](https://github.com/proyecto26/MyAPI)
324332

demo/Assets/MainScript.cs

+101-77
Original file line numberDiff line numberDiff line change
@@ -4,96 +4,120 @@
44
using Proyecto26;
55
using System.Collections.Generic;
66

7-
public class MainScript : MonoBehaviour {
7+
public class MainScript : MonoBehaviour
8+
{
9+
private readonly string basePath = "https://jsonplaceholder.typicode.com";
810

9-
private readonly string basePath = "https://jsonplaceholder.typicode.com";
10-
11-
private void LogMessage(string title, string message) {
11+
private void LogMessage(string title, string message)
12+
{
1213
#if UNITY_EDITOR
13-
EditorUtility.DisplayDialog (title, message, "Ok");
14+
EditorUtility.DisplayDialog(title, message, "Ok");
1415
#else
1516
Debug.Log(message);
1617
#endif
17-
}
18-
19-
public void Get(){
20-
21-
// We can add default request headers for all requests
22-
RestClient.DefaultRequestHeaders["Authorization"] = "Bearer ...";
18+
}
2319

24-
RequestHelper requestOptions = null;
20+
public void Get()
21+
{
22+
// We can add default request headers for all requests
23+
RestClient.DefaultRequestHeaders["Authorization"] = "Bearer ...";
2524

26-
RestClient.GetArray<Post>(basePath + "/posts").Then(res => {
27-
this.LogMessage ("Posts", JsonHelper.ArrayToJsonString<Post>(res, true));
28-
return RestClient.GetArray<Todo>(basePath + "/todos");
29-
}).Then(res => {
30-
this.LogMessage ("Todos", JsonHelper.ArrayToJsonString<Todo>(res, true));
31-
return RestClient.GetArray<User>(basePath + "/users");
32-
}).Then(res => {
33-
this.LogMessage ("Users", JsonHelper.ArrayToJsonString<User>(res, true));
25+
RequestHelper requestOptions = null;
3426

35-
// We can add specific options and override default headers for a request
36-
requestOptions = new RequestHelper {
37-
Uri = basePath + "/photos",
38-
EnableDebug = true,
39-
Headers = new Dictionary<string, string> {
40-
{ "Authorization", "Other token..." }
41-
}
42-
};
43-
return RestClient.GetArray<Photo>(requestOptions);
44-
}).Then(res => {
45-
this.LogMessage("Header", requestOptions.GetHeader("Authorization"));
27+
RestClient.GetArray<Post>(basePath + "/posts")
28+
.Then(res =>
29+
{
30+
this.LogMessage("Posts", JsonHelper.ArrayToJsonString<Post>(res, true));
31+
return RestClient.GetArray<Todo>(basePath + "/todos");
32+
})
33+
.Then(res =>
34+
{
35+
this.LogMessage("Todos", JsonHelper.ArrayToJsonString<Todo>(res, true));
36+
return RestClient.GetArray<User>(basePath + "/users");
37+
})
38+
.Then(res =>
39+
{
40+
this.LogMessage("Users", JsonHelper.ArrayToJsonString<User>(res, true));
4641

47-
// And later we can clean the default headers for all requests
48-
RestClient.ClearDefaultHeaders();
42+
// We can add specific options and override default headers for a request
43+
requestOptions = new RequestHelper
44+
{
45+
Uri = basePath + "/photos",
46+
EnableDebug = true,
47+
Headers = new Dictionary<string, string> {
48+
{ "Authorization", "Other token..." }
49+
}
50+
};
51+
return RestClient.GetArray<Photo>(requestOptions);
52+
})
53+
.Then(res =>
54+
{
55+
this.LogMessage("Header", requestOptions.GetHeader("Authorization"));
4956

50-
}).Catch(err => this.LogMessage ("Error", err.Message));
51-
}
57+
// And later we can clean the default headers for all requests
58+
RestClient.ClearDefaultHeaders();
5259

53-
public void Post(){
54-
55-
RestClient.Post<Post>(basePath + "/posts", new Post {
56-
title = "My first title",
57-
body = "My first message",
58-
userId = 26
59-
})
60-
.Then(res => this.LogMessage ("Success", JsonUtility.ToJson(res, true)))
61-
.Catch(err => this.LogMessage ("Error", err.Message));
62-
}
60+
})
61+
.Catch((RequestException err) => this.LogMessage("Error", err.Message))
62+
.Forget();
63+
}
6364

64-
public void Put(){
65+
public void Post()
66+
{
67+
RestClient.Post<Post>(basePath + "/posts", new Post
68+
{
69+
title = "My first title",
70+
body = "My first message",
71+
userId = 26
72+
})
73+
.Then(res => this.LogMessage("Success", JsonUtility.ToJson(res, true)))
74+
.Catch((RequestException err) => this.LogMessage("Error", err.Message))
75+
.Forget();
76+
}
6577

66-
RestClient.Put<Post>(new RequestHelper {
67-
Uri = basePath + "/posts/1",
68-
Body = new Post {
69-
title = "My new title",
70-
body = "My new message",
71-
userId = 26
72-
},
73-
Retries = 5,
74-
RetrySecondsDelay = 1,
75-
RetryCallback = (err, retries) => {
76-
Debug.Log(string.Format("Retry #{0} Status {1}\nError: {2}", retries, err.StatusCode, err));
77-
}
78-
}, (err, res, body) => {
79-
if(err != null){
80-
this.LogMessage ("Error", err.Message);
81-
}
82-
else{
83-
this.LogMessage ("Success", res.Text);
84-
}
85-
});
86-
}
78+
public void Put()
79+
{
80+
RestClient.Put<Post>(new RequestHelper
81+
{
82+
Uri = basePath + "/posts/1",
83+
Body = new Post
84+
{
85+
title = "My new title",
86+
body = "My new message",
87+
userId = 26
88+
},
89+
Retries = 5,
90+
RetrySecondsDelay = 1,
91+
RetryCallback = (err, retries) =>
92+
{
93+
Debug.Log(string.Format("Retry #{0} Status {1}\nError: {2}", retries, err.StatusCode, err));
94+
}
95+
}, (err, res, body) =>
96+
{
97+
if (err != null)
98+
{
99+
this.LogMessage("Error", err.Message);
100+
}
101+
else
102+
{
103+
this.LogMessage("Success", res.Text);
104+
}
105+
});
106+
}
87107

88-
public void Delete(){
108+
public void Delete()
109+
{
89110

90-
RestClient.Delete(basePath + "/posts/1", (err, res) => {
91-
if(err != null){
92-
this.LogMessage ("Error", err.Message);
93-
}
94-
else{
95-
this.LogMessage ("Success", "Status: " + res.StatusCode.ToString());
96-
}
97-
});
98-
}
111+
RestClient.Delete(basePath + "/posts/1", (err, res) =>
112+
{
113+
if (err != null)
114+
{
115+
this.LogMessage("Error", err.Message);
116+
}
117+
else
118+
{
119+
this.LogMessage("Success", "Status: " + res.StatusCode.ToString());
120+
}
121+
});
122+
}
99123
}

demo/Assets/Packages/RSG.Promise.3.0.1.meta renamed to demo/Assets/Packages/ProtoPromise.2.5.0.meta

+2-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/Assets/Packages/RSG.Promise.3.0.1/lib.meta renamed to demo/Assets/Packages/ProtoPromise.2.5.0/lib.meta

+2-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/Assets/Packages/RSG.Promise.3.0.1/lib/net35.meta renamed to demo/Assets/Packages/ProtoPromise.2.5.0/lib/net35.meta

+2-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)