Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / JSON

JsonSerializer

string JsonSerializer.Serialize(value) · T JsonSerializer.Deserialize<T>(json)

Turn a value into a JSON string and a JSON string into a typed object — the C#-faithful System.Text.Json spelling. `JsonSerializer.Serialize(order)` gives the JSON text; `JsonSerializer.Deserialize<Order>(body)` parses it back into a typed `Order`. Pure — no capability needed.

stable3 examples compiled by CIjsonserializationbcl

Summary#

JsonSerializer is the JSON surface, spelled exactly as in C# (System.Text.Json). It has two members:

var body = JsonSerializer.Serialize(order);              // a value → a JSON string
var order = JsonSerializer.Deserialize<Order>(body);     // a JSON string → a typed Order

It is pure — no capability, no using required (though a pasted using System.Text.Json; is accepted and does nothing). It pairs naturally with Http.*: serialize a request body, deserialize a response.

Signature#

string JsonSerializer.Serialize(value)          // value = a scalar, a class, a list, or a map
T      JsonSerializer.Deserialize<T>(string json) // T = a class

Description#

Serialize accepts any value and returns compact JSON (matching System.Text.Json's default): a scalar ("x", 42, true, 3.5), a class instance (→ a JSON object of its fields), a list (→ an array), a map (→ an object). Property names are the field names as declared. byte[] becomes base64.

Deserialize<T> parses JSON into a T, where T is a class — the DTO you want the data as. It fills each declared field from the matching JSON member, coercing by the field's type: scalars, a nested class (→ a nested object), and a collection (→ a list of elements). A member missing from the JSON is left at its default; a JSON null sets null. A field the class doesn't declare is ignored.

T must be a class, not an entity — an entity has identity and persistence a JSON body can't carry.

Storing it: the Json property type#

A property declared Json holds a document, and it is string-backed — so Serialize writes one and the property reads back into Deserialize:

class Detail { public int Attempt; public string Reason; }

entity Job { [Required, MaxLength(50)] string Name; Json Detail; }

void Record() {
  var j = new Job { Name = "j1", Detail = JsonSerializer.Serialize(new Detail { Attempt = 2, Reason = "retry" }) };
}

int Attempts(Job job) {
  return JsonSerializer.Deserialize<Detail>(job.Detail).Attempt;
}

That is the whole surface: a Json property takes a string and gives one back. It is not parsed or validated on the way in — the same rule a Markdown property follows — so Serialize is how you sensibly produce one rather than building the text by hand.

⚠ There is no object-literal form: Detail = new { attempt = 2 } does not compile, because an anonymous object is not a value in Osy#. Declare the shape as a class and serialize it, which is what you would do in C# anyway and gives the document a name the rest of your code can use.

Serializing an entity produces a shallow object: its Id and scalar properties, with an EntityRef rendered as its FK id (not the nested entity) and collections omitted. This is deliberate — expanding relations by default would invite reference cycles and load a record's whole object graph. When you want a specific nested shape, map the entity into a class DTO (which serializes fully) and serialize that.

Examples#

Round-trip a DTO through JSON:

class Order {
  public string Code;
  public decimal Total;
  public bool Paid;
}

string ToJson(Order o) {
  return JsonSerializer.Serialize(o);              // {"Code":"A1","Total":42.0,"Paid":true}
}

Order FromJson(string body) {
  return JsonSerializer.Deserialize<Order>(body);  // typed Order, fields populated
}

Parse an HTTP response body (Http.*):

app Shop {
  model "model/**/*.osy";
  use Osyrin.Http;       // `use` is a manifest declaration — Http.* needs it
}

class Weather { public decimal TempC; public string Summary; }

Weather Fetch(string city) {
  var r = Http.Get("https://api.example.com/weather/" + city);
  return r.IsSuccess ? JsonSerializer.Deserialize<Weather>(r.Body) : new Weather { Summary = "unknown" };
}

Nested classes and lists deserialize recursively:

class Line { public string Sku; public int Qty; }
class Cart { public string Owner; public List<Line> Lines; }

Cart Parse(string body) {
  return JsonSerializer.Deserialize<Cart>(body);   // Lines becomes a list of typed Line objects
}

See also#

  • Json — the Json property type this writes into, and when to reach for it
  • Http.* — the outbound HTTP surface whose bodies this serializes / parses
  • constructor — the class types Serialize walks and Deserialize targets

Related

Http.*

Make an outbound HTTP call to a URL you build at runtime — a webhook, a third-party API, a discovered endpoint…

constructor

A class declares one constructor — its name is the class name, it takes no return type, and it runs when you write new…

Json

A member that holds a JSON document — an object, an array, or any value. It is stored as real jsonb, and written and…