Lesson 19 · 19 of 20
JSON with fpjson · Pascal
Read and build JSON in Free Pascal with fpjson and jsonparser: walk an order, add up its lines and reply with a brand new JSON object.

The `fpjson` unit represents JSON as Pascal objects (TJSONObject, TJSONArray, numbers and strings), and `jsonparser` adds the parser. `GetJSON` turns the Incoming text into that tree and returns the root, which is treated as an object here with as TJSONObject.
Values are read by name and type: order.Integers['id'], line.Strings['sku'], order.Arrays['lines']. `FindPath('customer.name')` goes down several levels at once using a dot-separated path. If a name is missing or the type does not match, an exception is raised.
The for item in loop walks the array of lines; each item is a TJSONEnum and its Value is the line object. The total is added up in whole cents, which also sidesteps an fpjson quirk: numbers with decimals come out in scientific notation when turned into text.
To build JSON, TJSONObject.Create([...]) takes name-value pairs, and Add appends more, even a whole TJSONArray. `AsJSON` writes it on one line (FormatJSON would indent it). Every object owns what it contains: a single Free on the root releases the whole tree, and the two try ... finally blocks make sure that happens.
Code · main.pas
program main;uses SysUtils, fpjson, jsonparser;const Incoming = '{"id": 1042, "customer": {"name": "Lucia Romero", "city": "Malaga"},' + ' "lines": [{"sku": "MUG-01", "qty": 2, "cents": 850},' + ' {"sku": "TEA-12", "qty": 1, "cents": 1295}]}';var order, line, reply: TJSONObject; item: TJSONEnum; total: Integer = 0;begin order := GetJSON(Incoming) as TJSONObject; // parse the text into objects try WriteLn('Order ', order.Integers['id'], ' for ', order.FindPath('customer.name').AsString); for item in order.Arrays['lines'] do begin line := item.Value as TJSONObject; WriteLn(' ', line.Strings['sku'], ' x', line.Integers['qty']); total := total + line.Integers['qty'] * line.Integers['cents']; end; reply := TJSONObject.Create(['order', order.Integers['id'], 'status', 'confirmed']); try reply.Add('total_cents', total); reply.Add('tags', TJSONArray.Create(['paid', 'gift'])); // reply owns it now WriteLn(reply.AsJSON); finally reply.Free; // frees everything inside too end; finally order.Free; end;end.Output · fpc main.pas && ./main
Order 1042 for Lucia Romero
MUG-01 x2
TEA-12 x1
{ "order" : 1042, "status" : "confirmed", "total_cents" : 2995, "tags" : ["paid", "gift"] }Key points
GetJSONturns text into a tree of JSON objects.Integers[...],Strings[...]andArrays[...]read by name and type.FindPath('a.b')goes down several levels at once.TJSONObject.Create([...])andAddbuild JSON;AsJSONwrites it.- Freeing the root frees everything inside it.
Exercise
Add a shipping object to the reply with the customer's city (order.FindPath('customer.city').AsString) and an express field set to True.