Easy HTTP (POST) communication with UnityWebRequest

Good work today.
This is Matsuyama from the Systems Development Department.
This time, I'll be writing about HTTP (POST) communication using UnitWebRequest.
It feels a bit late to be doing this, but I've only implemented communication via www so I thought I'd revisit it ^^;
What to make
- Use UnitWebRequest for HTTP (POST) communication
; requests and responses are in JSON format
; designed to be simple with the assumption of creating multiple communication APIs.
*Created with Unity 2019.3.5f1
JSON
First, regarding JSON, we will implement it using Unity's JsonUtility.
JsonUtility is a JSON parser provided by Unity that
can easily serialize classes and structs specified as Serializable.
Although there are limitations, such as the lack of support for Dictionary types, it seems to be superior to other JSON parsers in terms of performance.
Serializing into JSON format
UnityWebRequest
This is the main communication processing part.
allows you to handle HTTP requests and responses.
UnityWebRequest
The process itself was written quite simply.
A UnityWebRequest is generated in POST format, and the request parameters are set in JSON format.
// Set HTTP (POST) information var req = new UnityWebRequest(url, "POST"); req.uploadHandler = (UploadHandler)new UploadHandlerRaw(postData); req.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); req.SetRequestHeader("Content-Type", "application/json");
One thing to note is that the parameter cannot be passed as a string, so you will need to convert it to a byte array
// Convert the request object to JSON (byte array) string reqJson = JsonUtility.ToJson(request); byte[] postData = System.Text.Encoding.UTF8.GetBytes(reqJson);
When you're ready, submit your request
// API communication (wait for completion) yield return req.SendWebRequest();
The communication was determined to be successful because both isNetworkError and isHttpError were false.
The response will be stored in downloadHandler in JSON format (text).
// Communication result if (req.isNetworkError || req.isHttpError) // Failure { Debug.Log("Network error:" + req.error); } else // Success { Debug.Log("Succeeded:" + req.downloadHandler.text); }
API Control
The idea is to create API classes that define the requests and responses for each API, using the above-mentioned communication processing as a base class.
Specifically, it would look something like this:
Create structs for requests and responses with the Serializable attribute and define the parameters.
The URL for communication will have a common part defined in the base class, so only the API name at the end needs to be defined.
using System; using System.Collections.Generic; namespace Api { ///<summary> /// API Sample B ///</summary> public class SampleB : Web.ApiBase { public const string Name = "Test/SampleB"; ///<summary> /// Request parameters ///</summary> [Serializable] public struct Request { public string userId; public List<int> values; } public Request request; ///<summary> /// Response parameters ///</summary> [Serializable] public struct Response { public int count; public List<int> values; } public Response response; } }
How to use
First, generate the API classes mentioned above
private Api.SampleB apiB; private Web.ApiBase.Result result; private void Start() { // Create a class for communication apiB = new Api.SampleB(); // API communication sendApiB(); }
After specifying the API name, you set the values to be passed to the request structure.
Within the `Send()` method, it's serialized into JSON format and sent via HTTP (POST) communication using UnityWebRequest.
A callback is received upon completion of the communication, and the data is deserialized into a response structure.
While you would normally write code to process the response based on its content, this sample simply outputs to the console.
///<summary> /// API Sample B Communication ///</summary> private void sendApiB() { // Set the endpoint apiB.EndPoint = Api.SampleB.Name; // Set the request parameters apiB.request.userId = "beyondB"; apiB.request.values = new List<int> () { 1, 10, 100, 1000 }; // Communication apiB.Send<Api.SampleB.Request> (ref apiB.request, result => { // Result if (result.isSucceeded) // Success { // Expand response apiB.response = apiB.Response<Api.SampleB.Response> (); // Check the contents Debug.Log("SampleB Succeed!!"); Debug.Log(" count : " + apiB.response.count); foreach(var v in apiB.response.values) { Debug.Log(" val : " + v); } } else // Failed { Debug.Log("SampleB Failed : " + result.error); } }); }
summary
In this way, we were able to write HTTP communication processing in a fairly simple manner.
I think it should be usable for practical purposes.
Since it is communication processing, it will not work without server-side implementation, but I will upload the sample code to GitHub anyway.
Unity Sample
The sample base class does not inherit from MonoBehaviour, so coroutines could not be used directly.
This was addressed by referring to the following:
Using coroutines in classes that do not inherit from MonoBehaviour.
lastly
I have launched "SEKARAKU Lab," a service site for the system development company I belong to.
Beyond offers a one-stop service for everything from server design and construction to operation, so please feel free to contact us if you have any problems with server-side development.
SEKARAKU Lab:[https://sekarakulab.beyondjapan.com/](https://sekarakulab.beyondjapan.com/)
Well, that's all for today
3
