# [Newtonsoft Json Unity Package](https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@3.0)
* [JSON](https://www.json.org/json-en.html)
* [ECMA-404 - Ecma International - The JSON data interchange syntax](https://www.ecma-international.org/publications-and-standards/standards/ecma-404/)
* [Representational state transfer (REST)](https://en.wikipedia.org/wiki/Representational_state_transfer)
* [API 是什麼? RESTful API 又是什麼?. API ? RESTful API ? HTTP ? | by itsems | itsems_frontend | Medium](https://medium.com/itsems-frontend/api-%E6%98%AF%E4%BB%80%E9%BA%BC-restful-api-%E5%8F%88%E6%98%AF%E4%BB%80%E9%BA%BC-a001a85ab638)
* [Test a REST API with curl | Baeldung](https://www.baeldung.com/curl-rest)
* [ASP.NET Web APIs | Rest APIs with .NET and C#](https://dotnet.microsoft.com/en-us/apps/aspnet/apis)
* [Tutorial: Make HTTP requests in a .NET console app using C# | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient)
* [Convert JSON to C# Classes Online - Json2CSharp Toolkit](https://json2csharp.com/)
* [typicode/json-server: Get a full fake REST API with zero coding in less than 30 seconds (seriously)](https://github.com/typicode/json-server)
* [REST Client - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)
{%youtube K6Ee0SfxKV4 %}
* [HTTPie – API testing client that flows with you](https://httpie.io/)
* [Creating A RESTful Web Client With Unity Engine Networking API - HTTP GET, POST, PUT, and DELETE | Dilmer Valecillos](https://youtu.be/dGrgy2dAvSI)
{%youtube dGrgy2dAvSI %}
* [Rest Client for Unity | Network | Unity Asset Store](https://assetstore.unity.com/packages/tools/network/rest-client-for-unity-102501)
* [[Unity] 使用 Newtonsoft Json 解決 JsonUtility 無法序列化自訂類別問題 - kculwpvalxe的創作 - 巴哈姆特](https://home.gamer.com.tw/artwork.php?sn=5184668)
* [Newtonsoft Json Unity Package | Newtonsoft Json | 3.0](https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@3.0)
* https://github.com/needle-mirror/com.unity.nuget.newtonsoft-json
---
## json-server Example
db.json
```json=
{
"menus": [
{
"id": 1,
"value": "File",
"popup": {
"menuitem": [
{
"value": "New",
"onclick": "CreateNewDoc()"
},
{
"value": "Open",
"onclick": "OpenDoc()"
},
{
"value": "Close",
"onclick": "CloseDoc()"
}
]
}
}
]
}
```
```bash=
json-server --watch db.json
```
---
## Unity Rest Example
### Add Newtonsoft.Json Dependency
Packages/manifest.json
```json=
{
"dependencies": {
...,
"com.unity.nuget.newtonsoft-json": "3.0.1"
}
}
```
### Scripts
Assets/Scripts/RestExample/Models.cs
```csharp=
using System;
using System.Collections.Generic;
namespace RestExample.Models
{
[Serializable]
public class Menuitem
{
public string value { get; set; }
public string onclick { get; set; }
}
[Serializable]
public class Popup
{
public IList<Menuitem> menuitem { get; set; }
}
[Serializable]
public class Menu
{
public long id { get; set; }
public string value { get; set; }
public Popup popup { get; set; }
}
}
```
Assets/Scripts/RestExample/MenuRestClient.cs
```csharp=
using Newtonsoft.Json;
using RestExample.Models;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
namespace RestExample
{
enum CRUD { Create, Read, Update, Delete };
/// <summary>
/// REST controller for managing menu
/// Using Newtonsoft Json Unity Package
/// </summary>
public class MenuRestClient : MonoBehaviour
{
[SerializeField]
[Range(0.1f, 120.0f)]
[Tooltip("Time Remaining (seconds)")]
private float timeRemaining = 10;
[SerializeField]
[Tooltip("REST Service Endpoint Base URL")]
private string url = "http://localhost:3000";
private float time = 0;
private const string path = "menus";
private long currentId = 1;
private CRUD crud = CRUD.Create;
/// <summary>
/// GET /menus : get all the menus
/// </summary>
public void All()
{
UnityWebRequest www = UnityWebRequest.Get(new Uri($"{url}/{path}"));
try
{
www.SendWebRequest().completed += op =>
{
List<Menu> menus = JsonConvert.DeserializeObject<List<Menu>>(www.downloadHandler.text);
Debug.Log($"Code: {www.responseCode} --- list all ---\n{JsonConvert.SerializeObject(menus)}");
};
}
catch (Exception ex)
{
Debug.LogError(ex);
}
}
/// <summary>
/// GET /menus/{id}: get the "id" menu
/// </summary>
/// <param name="id">the id of the menu to retrieve</param>
public void Get(long id)
{
UnityWebRequest www = UnityWebRequest.Get(new Uri($"{url}/{path}/{id}"));
try
{
www.SendWebRequest().completed += op =>
{
Menu menu = JsonConvert.DeserializeObject<Menu>(www.downloadHandler.text);
currentId = menu.id;
Debug.Log($"Code: {www.responseCode} --- read id: {currentId} ---\n{JsonConvert.SerializeObject(menu)}");
};
}
catch (Exception ex)
{
Debug.LogError(ex);
}
}
/// <summary>
/// POST /menus: Create a new menu
/// </summary>
/// <param name="menu">the menu to create</param>
public void Post(Menu menu)
{
UnityWebRequest www = new UnityWebRequest(new Uri($"{url}/{path}"), UnityWebRequest.kHttpVerbPOST)
{
uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(menu)))
{
contentType = "application/json; charset=utf-8"
},
downloadHandler = new DownloadHandlerBuffer()
};
www.SetRequestHeader("Accept", "application/json");
try
{
www.SendWebRequest().completed += op =>
{
Menu menu = JsonConvert.DeserializeObject<Menu>(www.downloadHandler.text);
currentId = menu.id;
Debug.Log($"Code: {www.responseCode} --- create id: {currentId} ---\n{JsonConvert.SerializeObject(menu)}");
};
}
catch (Exception ex)
{
Debug.LogError(ex);
}
}
/// <summary>
/// PUT /menus/{id}: Updates an existing menu
/// </summary>
/// <param name="menu">the menu to update</param>
public void Put(Menu menu)
{
UnityWebRequest www = new UnityWebRequest(new Uri($"{url}/{path}/{menu.id}"), UnityWebRequest.kHttpVerbPUT)
{
uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(menu)))
{
contentType = "application/json; charset=utf-8"
},
downloadHandler = new DownloadHandlerBuffer()
};
www.SetRequestHeader("Accept", "application/json");
try
{
www.SendWebRequest().completed += op =>
{
Menu newMenu = JsonConvert.DeserializeObject<Menu>(www.downloadHandler.text);
Debug.Log($"Code: {www.responseCode} --- update id: {newMenu.id} ---");
Debug.Log(JsonConvert.SerializeObject(newMenu));
};
}
catch (Exception ex)
{
Debug.LogError(ex);
}
}
/// <summary>
/// DELETE /menus/{id}: delete the "id" menu
/// </summary>
/// <param name="id">the id of the menu to delete</param>
public void Delete(long id)
{
UnityWebRequest www = UnityWebRequest.Delete(new Uri($"{url}/{path}/{id}"));
try
{
www.SendWebRequest().completed += op =>
{
Debug.Log($"Code: {www.responseCode} --- delete id: {id} ---");
};
}
catch (Exception ex)
{
Debug.LogError(ex);
}
}
// Update is called once per frame
void Update()
{
if (time > 0)
{
time -= Time.deltaTime;
}
else
{
switch (crud)
{
case CRUD.Create:
{
Menu menu = new Menu
{
value = "Create 新增",
popup = new Popup
{
menuitem = new List<Menuitem>
{
new Menuitem
{
value = "Save",
onclick = "SaveDoc()"
}
}
}
};
Post(menu);
crud = CRUD.Read;
}
break;
case CRUD.Read:
{
Get(currentId);
All();
crud = CRUD.Update;
}
break;
case CRUD.Update:
{
Menu menu = new Menu
{
id = currentId,
value = "Update 修改",
popup = new Popup
{
menuitem = new List<Menuitem>
{
new Menuitem
{
value = "Save",
onclick = "SaveDoc()"
},
new Menuitem
{
value = "Edit",
onclick = "EditDoc()"
}
}
}
};
Put(menu);
crud = CRUD.Delete;
}
break;
case CRUD.Delete:
{
Delete(currentId);
crud = CRUD.Create;
}
break;
}
time = timeRemaining;
}
}
}
}
```
Add MenuRestClient script to GameObject in Scene

