WebRequest
A robust HTTP client solution for Unity, offering flexible API management, automatic retries, and comprehensive request handling using .NET's HttpClient.
In One Line
REST assured, your requests are in good hands!
Overview
AceLand WebRequest is a modern web request solution designed specifically for Unity projects, providing a fluent interface for API calls with built-in error handling, retry mechanisms, and API section management. It uses .NET's HttpClient instead of UnityWebRequest for better performance and more control.
Package Info
display name
AceLand WebRequest
package name
com.aceland.webrequest
latest version
1.0.10
namespace
AceLand.WebRequest
git repository
dependencies
com.aceland.library: 1.0.18
com.aceland.taskutils: 1.0.6
com.unity.nuget.newtonsoft-json: 3.2.1
Why Use It?
Modern Architecture: Built on .NET's HttpClient for better performance and reliability
Flexible API Management: Test and switch between different API configurations in editor
Built-in Retry Logic: Automatic retry mechanism with configurable intervals
Type-Safe Builder Pattern: Fluent interface for building requests with compile-time safety
Comprehensive Error Handling: Detailed error logging and exception management
Multiple Content Types: Support for JSON, Form, and Multipart request types
Key Features
Custom retry intervals and timeout settings
Comprehensive logging system with different build levels
HTTPS enforcement option
Automatic timestamp header injection
JSON validation before sending
Support for cancellation tokens
Editor tools for API section management
Project Settings
Logging
---
Logging Level
Level of Logging on web request
default: BuildLevel.Production
Result Logging Level
Level of Logging on request success
default: BuildLevel.DevelopmentBuild
Checking Options
---
Check Json Before Send
Check given content is a valid json before send request.
This may be expensive if big content.
Default: false
Force Https Scheme
Require request url is https if true. Otherwise http will also ok.
Default: true
Header Auto Fill
---
Add Time In Header
Add send time in header automatically.
Default: true
Time Key
key of Time in header.
default: Time
Auto Fill Headers
Add default headers on each Request.
Same headers will be covered by WithHeaders options on building Request.
Default: { "User-Agent", "Mozilla/5.0" }
Request Options
---
Request Timeout
Default timeout if not set in request handle.
Default: 3000
ms
Long Request Timeout
Default long request timeout. It will be set if building request handle with long request.
Default: 15000
ms
Request Retry
How many times will retry on connection error including timeout.
Default: 3
Retry Interval
Interval between each retry.
Default: [ 400, 800, 1600, 3200, 6400, 12800, 25600]
in ms
Current API Section
---
Section
[Lock] Current API section.
Domain
[Lock] Current API Domain.
Version
[Lock] Current API Version.
-
button
Clear Current API Section Data.
Api Url
[Lock] API URL of current section.
API Section Editor
---
Table
This is API Sections Data. All data is saved in
Assets/Editor/AceLand/api_sections.asset
that confirms non-used data will not be built.
Last line is an empty line for adding new data.
-
delete data *
apply to Current API Section
+
add data
Save
save to asset Restore
restore unsaved changes
Usage
// Create a GET Request Handler
IRequestHandle request = Request.Get()
.WithUrl("https://api.example.com/data".ToUri())
.WithHeader("User-Agent", "MyUnityApp/1.0")
.Build();
// Create a POST Request Handler
IRequestHandle request = Request.Post()
.WithUrl("https://api.example.com/users".ToUri())
.WithJsonContent()
.WithContent("{\"name\": \"John\"}")
.WithHeader("Authorization", "Bearer token")
.WithTimeout(7500)
.Build();
// Create a POST Request Handler with Multipart form data with file
IRequestHandle request = Request.Post()
.WithUrl("https://api.example.com/upload".ToUri())
.WithMultipartContent()
.WithStreamData("file", "path/to/file.jpg", "image.jpg")
.WithContent("description", "Profile photo")
.Build();
// Send the request and get reponse
JToken response = await request.Send();
// Send the request and receive specified type of data
YourData response = await request.Send<YourData>();
// Cancel the request
request.Cancel();
// Dispose the request
request.Disposal();
// Get result from finished request
JToken result = request.Result;
Sample of Weather Widget
For example, there is a Weather Widget on canvas. It will refresh every set time.
using System.Threading;
using System.Threading.Tasks;
using AceLand.TaskUtils;
using AceLand.WebRequest;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class TestWeatherWidget : MonoBehaviourr
{
[Header("Weather Widget")]
// WeatherProfile contains sprite of weather state
[SerializeField] private WeatherProfile profile;
// HongKongLocations contains districts and coordinates
[SerializeField] private HongKongLocations location = HongKongLocations.CentralAndWestern;
[SerializeField] private int updateInterval = 180;
[SerializeField] private Image weatherIcon;
[SerializeField] private TextMeshProUGUI tempLabel;
[SerializeField] private TextMeshProUGUI apparentTempLabel;
// setup API
private const string LATITUDE_KEY = "{latitude}";
private const string LONGITUDE_KEY = "{longitude}";
private const string API = "https://api.open-meteo.com/v1/" +
"forecast?latitude=" + LATITUDE_KEY +
"&longitude=" + LONGITUDE_KEY +
"¤t=temperature_2m,weather_code,rain,cloud_cover,showers,apparent_temperature,is_day" +
"&timezone=auto" +
"&forecast_days=1";
private CancellationTokenSource _tokenSource;
private void Start()
{
_tokenSource = new CancellationTokenSource();
// Linked with Application Alive Token
var token = Promise.LinkedOrApplicationAliveToken(_tokenSource, out _);
RequestWebData(token);
}
private void OnDisable()
{
if (!_tokenSource.IsCancellationRequested)
_tokenSource?.Cancel();
_tokenSource?.Dispose();
}
private void UpdateWeather(WeatherWidgetData data)
{
weatherIcon.sprite = profile.GetIcon(data.WeatherCode, data.IsDay);
tempLabel.text = data.Temperature;
apparentTempLabel.text = $"Apparent: {data.ApparentTemperature}";
}
private void RequestWebData(CancellationToken token)
{
if (token.IsCancellationRequested) return;
var (latitude, longitude) = location.ToGeoData();
Uri api = API.Replace(LATITUDE_KEY, latitude.ToString("F4"))
.Replace(LONGITUDE_KEY, longitude.ToString("F4"))
.ToUri();
int intervalTime = updateInterval * 1000;
// create request
IRequestHandle request = Request.Get()
.WithUrl(api)
.Build();
// send request
request.Send<WeatherWebData>()
.Then(result =>
{
// convert data
WeatherWidgetData widgetData = result.ToWidgetData(location);
// use data
UpdateWeather(widgetData);
// prepare next call
WaitForRefresh(intervalTime, token);
})
.Catch(exception =>
{
// prepare next call
WaitForRefresh(intervalTime, token);
})
.Final(() =>
{
// dispose current request
request.Dispose();
});
}
private void WaitForRefresh(int intervalTime, CancellationToken token)
{
if (token.IsCancellationRequested) return;
// wait for next call
Task.Delay(intervalTime, token)
.Then(() => RequestWebData(token));
}
}
Advanced Sample
This is a sample of building a User Authorization API serivce and how to use it.
using System.Threading.Tasks;
using AceLand.WebRequest;
// create a base class containing main urls
public abstract class BaseAPI
{
// reference to Api Url in Project Setting
private protected static string APIUrl => Request.ApiUrl;
}
// create UserAPI Service
public sealed class UserAPI : BaseAPI
{
// prepare all api urls.
private const string BASIC_AUTH_URL = "/basic-auth/{user}/{passwd}";
private static IRequestHandle _request;
// create a Promise to disposal request handle on finished
public static Promise<UserData> BasicAuth(string user, string password)
{
// combine a complete URL
string url = APIUrl + BASIC_AUTH_URL
.Replace("{user}", user)
.Replace("{passwd}", password);
// build Request Handle
_request = Request.Get()
.WithUrl(url.ToUri())
.Build();
// await response with specified type
return _request.Send<UserData>()
.Final(_request.Disposal);
}
public static async CancelBasicAuth()
{
_request?.Cancel();
}
}
Last updated