Skip to content

Commit

Permalink
Merge pull request #98 from proyecto26/develop
Browse files Browse the repository at this point in the history
Added Query string utilities
  • Loading branch information
jdnichollsc authored Sep 20, 2019
2 parents 009e2f2 + 0f84d23 commit 10b977b
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- Supporting retrieving a JSON Array from a POST request by [@Coeur](https://github.com/Coeur) ([7cc54bb](https://github.com/proyecto26/RestClient/pull/97/commits/7cc54bbbace4d5207efbb0b82de3a5d71aafc080)).
- Added Query string utilities.

## [2.5.9] - 2019-09-08

### Added
Expand Down
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ RestClient.Request(new RequestHelper {
Uri = "https://jsonplaceholder.typicode.com/photos",
Method = "POST",
Timeout = 10,
Params = new Dictionary<string, string> {
{ "param1", "Query string param..." }
},
Headers = new Dictionary<string, string> {
{ "Authorization", "Bearer JWT_token..." }
},
Expand Down Expand Up @@ -217,18 +220,26 @@ RestClient.Put<CustomResponse>(usersRoute + "/1", updatedUser).Then(customRespon
});
```

## Custom HTTP Headers and Options 💥
## Custom HTTP Headers, Params and Options 💥
**HTTP Headers**, such as `Authorization`, can be set in the **DefaultRequestHeaders** object for all requests
```csharp
RestClient.DefaultRequestHeaders["Authorization"] = "Bearer ...";
```

Also we can add specific options and override default headers for a request
**Query string params** can be set in the **DefaultRequestParams** object for all requests
```csharp
RestClient.DefaultRequestParams["param1"] = "Query string value...";
```

Also we can add specific options and override default headers and params for a request
```csharp
var currentRequest = new RequestHelper {
Uri = "https://jsonplaceholder.typicode.com/photos",
Headers = new Dictionary<string, string> {
{ "Authorization", "Other token..." }
},
Params = new Dictionary<string, string> {
{ "param1", "Other value..." }
}
};
RestClient.GetArray<Photo>(currentRequest).Then(response => {
Expand All @@ -245,9 +256,10 @@ currentRequest.DownloadedBytes; //The number of bytes of body data the system ha
currentRequest.Abort(); //Abort the request manually
```

Later we can clean the default headers for all requests
Later we can clear the default headers and params for all requests
```csharp
RestClient.CleanDefaultHeaders();
RestClient.ClearDefaultHeaders();
RestClient.ClearDefaultParams();
```

### Example
Expand Down
Binary file modified doc/RestClient.docx
Binary file not shown.
Binary file modified doc/RestClient.pdf
Binary file not shown.
52 changes: 49 additions & 3 deletions src/Proyecto26.RestClient/Helpers/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Text;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

Expand All @@ -10,13 +10,19 @@ public static class Extensions
/// <summary>
/// Create an object with the response of the server
/// </summary>
/// <returns>An object with the response.</returns>
/// <param name="request">An UnityWebRequest object.</param>
/// <returns>An object with the response.</returns>
public static ResponseHelper CreateWebResponse(this UnityWebRequest request)
{
return new ResponseHelper(request);
}

/// <summary>
/// Validate if the request is OK with the current options
/// </summary>
/// <param name="request">An UnityWebRequest object.</param>
/// <param name="options">The options of the request.</param>
/// <returns>A boolean that indicates if the request is valid.</returns>
public static bool IsValidRequest(this UnityWebRequest request, RequestHelper options)
{
return request.isDone &&
Expand All @@ -25,5 +31,45 @@ public static bool IsValidRequest(this UnityWebRequest request, RequestHelper op
!request.isHttpError || options.IgnoreHttpException
);
}

/// <summary>
/// Escapes characters in a string to ensure they are URL-friendly
/// </summary>
/// <param name="queryParam">A query string param</param>
/// <returns>Escaped query string param.</returns>
public static string EscapeURL(this string queryParam)
{
#if UNITY_2018_3_OR_NEWER
return UnityWebRequest.EscapeURL(queryParam);
#else
return WWW.EscapeURL(queryParam);
#endif
}

/// <summary>
/// Generate the url and escape params
/// </summary>
/// <param name="uri">The URI of the resource to retrieve via HTTP.</param>
/// <param name="queryParams">Query string parameters.</param>
/// <returns>The full url with query string params.</returns>
public static string BuildUrl(this string uri, Dictionary<string, string> queryParams)
{
var url = uri;
var defaultParams = RestClient.DefaultRequestParams;
if (defaultParams.Any() || queryParams.Any())
{
var urlParamKeys = queryParams.Keys;
url += (url.Contains("?") ? "&" : "?") + string.Join("&",
queryParams
.Concat(
defaultParams
.Where(p => !urlParamKeys.Contains(p.Key))
)
.Select(p => string.Format("{0}={1}", p.Key, p.Value.EscapeURL()))
.ToArray()
);
}
return url;
}
}
}
16 changes: 9 additions & 7 deletions src/Proyecto26.RestClient/Helpers/HttpBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ public static IEnumerator CreateRequestAndRetry(RequestHelper options, Action<Re
var response = request.CreateWebResponse();
if (request.IsValidRequest(options))
{
DebugLog(options.EnableDebug, string.Format("Url: {0}\nMethod: {1}\nStatus: {2}\nResponse: {3}", options.Uri, options.Method, request.responseCode, options.ParseResponseBody ? response.Text : "body not parsed"), false);
DebugLog(options.EnableDebug, string.Format("RestClient - Response\nUrl: {0}\nMethod: {1}\nStatus: {2}\nResponse: {3}", options.Uri, options.Method, request.responseCode, options.ParseResponseBody ? response.Text : "body not parsed"), false);
callback(null, response);
break;
}
else if (!options.IsAborted && retries < options.Retries)
{
yield return new WaitForSeconds(options.RetrySecondsDelay);
retries++;
if(options.RetryCallback != null)
if (options.RetryCallback != null)
{
options.RetryCallback(CreateException(options, request), retries);
}
DebugLog(options.EnableDebug, string.Format("Retry Request\nUrl: {0}\nMethod: {1}", options.Uri, options.Method), false);
DebugLog(options.EnableDebug, string.Format("RestClient - Retry Request\nUrl: {0}\nMethod: {1}", options.Uri, options.Method), false);
}
else
{
Expand All @@ -47,13 +47,15 @@ public static IEnumerator CreateRequestAndRetry(RequestHelper options, Action<Re

private static UnityWebRequest CreateRequest(RequestHelper options)
{
var url = options.Uri.BuildUrl(options.Params);
DebugLog(options.EnableDebug, string.Format("RestClient - Request\nUrl: {0}", url), false);
if (options.FormData is WWWForm && options.Method == UnityWebRequest.kHttpVerbPOST)
{
return UnityWebRequest.Post(options.Uri, options.FormData);
return UnityWebRequest.Post(url, options.FormData);
}
else
{
return new UnityWebRequest(options.Uri, options.Method);
return new UnityWebRequest(url, options.Method);
}
}

Expand Down Expand Up @@ -89,7 +91,7 @@ public static IEnumerator DefaultUnityWebRequest<TResponse>(RequestHelper option
}
catch (Exception error)
{
DebugLog(options.EnableDebug, string.Format("Invalid JSON format\nError: {0}", error.Message), true);
DebugLog(options.EnableDebug, string.Format("RestClient - Invalid JSON format\nError: {0}", error.Message), true);
err = new RequestException(error.Message);
}
finally
Expand All @@ -110,7 +112,7 @@ public static IEnumerator DefaultUnityWebRequest<TResponse>(RequestHelper option
}
catch (Exception error)
{
DebugLog(options.EnableDebug, string.Format("Invalid JSON format\nError: {0}", error.Message), true);
DebugLog(options.EnableDebug, string.Format("RestClient - Invalid JSON format\nError: {0}", error.Message), true);
err = new RequestException(error.Message);
}
finally
Expand Down
17 changes: 17 additions & 0 deletions src/Proyecto26.RestClient/Helpers/RequestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,23 @@ public Dictionary<string, string> Headers
set { _headers = value; }
}

private Dictionary<string, string> _params;
/// <summary>
/// The HTTP query string params to send with the request
/// </summary>
public Dictionary<string, string> Params
{
get
{
if (_params == null)
{
_params = new Dictionary<string, string>();
}
return _params;
}
set { _params = value; }
}

private bool _parseResponseBody = true;
/// <summary>
/// Whether to parse the response body as JSON or not. Note: parsing a large non-text file will have severe performance impact.
Expand Down
28 changes: 28 additions & 0 deletions src/Proyecto26.RestClient/Helpers/ResponseHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,27 @@ namespace Proyecto26
[Serializable]
public class ResponseHelper
{
/// <summary>
/// The UnityWebRequest used in the current request.
/// </summary>
public UnityWebRequest Request { get; private set; }

public ResponseHelper(UnityWebRequest request)
{
Request = request;
}

/// <summary>
/// The numeric HTTP response code returned by the server.
/// </summary>
public long StatusCode
{
get { return Request.responseCode; }
}

/// <summary>
/// Returns the raw bytes downloaded from the remote server, or null.
/// </summary>
public byte[] Data
{
get {
Expand All @@ -36,6 +45,9 @@ public byte[] Data
}
}

/// <summary>
/// Returns the bytes from data interpreted as a UTF8 string.
/// </summary>
public string Text
{
get
Expand All @@ -53,16 +65,32 @@ public string Text
}
}

/// <summary>
/// A human-readable string describing any system errors encountered by the UnityWebRequest object of this response while handling HTTP requests or responses.
/// </summary>
public string Error
{
get { return Request.error; }
}

/// <summary>
/// Get response headers
/// </summary>
public Dictionary<string, string> Headers
{
get { return Request.GetResponseHeaders(); }
}

/// <summary>
/// Get the value of a header
/// </summary>
/// <returns>The string value of the header.</returns>
/// <param name="name">The name of the header.</param>
public string GetHeader(string name)
{
return this.Request.GetResponseHeader(name);
}

public override string ToString()
{
return JsonUtility.ToJson(this, true);
Expand Down
4 changes: 2 additions & 2 deletions src/Proyecto26.RestClient/Helpers/StaticCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public static class StaticCoroutine
private class CoroutineHolder : MonoBehaviour { }

private static CoroutineHolder _runner;
private static CoroutineHolder runner
private static CoroutineHolder Runner
{
get
{
Expand All @@ -23,7 +23,7 @@ private static CoroutineHolder runner

public static Coroutine StartCoroutine(IEnumerator coroutine)
{
return runner.StartCoroutine(coroutine);
return Runner.StartCoroutine(coroutine);
}
}
}
2 changes: 1 addition & 1 deletion src/Proyecto26.RestClient/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.

[assembly: AssemblyVersion ("2.5.9")]
[assembly: AssemblyVersion ("2.6.0")]

// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
Expand Down
2 changes: 1 addition & 1 deletion src/Proyecto26.RestClient/Proyecto26.RestClient.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Proyecto26.RestClient</id>
<version>2.5.9</version>
<version>2.6.0</version>
<title>RestClient for Unity</title>
<authors>Juan David Nicholls Cardona</authors>
<owners>jdnichollsc</owners>
Expand Down
44 changes: 40 additions & 4 deletions src/Proyecto26.RestClient/RestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,50 @@ namespace Proyecto26
{
/// <summary>
/// RestClient for Unity
/// Version: 2.5.9
/// Version: 2.6.0
/// </summary>
public static partial class RestClient
{
#region Common

/// <summary>
/// The default request headers.
/// Gets the version of the RestClient library.
/// </summary>
public static System.Version Version
{
get
{
return typeof(RestClient).Assembly.GetName().Version;
}
}

/// <summary>
/// Default query string params.
/// </summary>
private static Dictionary<string, string> _defaultRequestParams;
public static Dictionary<string, string> DefaultRequestParams
{
get
{
if (_defaultRequestParams == null)
{
_defaultRequestParams = new Dictionary<string, string>();
}
return _defaultRequestParams;
}
set { _defaultRequestParams = value; }
}

/// <summary>
/// Clear default query string params.
/// </summary>
public static void ClearDefaultParams()
{
DefaultRequestParams.Clear();
}

/// <summary>
/// Default headers.
/// </summary>
private static Dictionary<string, string> _defaultRequestHeaders;
public static Dictionary<string, string> DefaultRequestHeaders
Expand All @@ -33,9 +69,9 @@ public static Dictionary<string, string> DefaultRequestHeaders
}

/// <summary>
/// Cleans the default headers.
/// Clear default headers.
/// </summary>
public static void CleanDefaultHeaders()
public static void ClearDefaultHeaders()
{
DefaultRequestHeaders.Clear();
}
Expand Down

0 comments on commit 10b977b

Please sign in to comment.