# "Payload Encoding" _Path: en/lua/data/payload_ > "Convert data between formats including JSON, MessagePack, and binary. Handle typed payloads for inter-service communication and workflow data passing." ## Table of Contents - Payload Encoding ## Content # Payload Encoding Payloads carry typed values between functions, processes, services, and workflows. They can be inspected, extracted, or transcoded between supported formats. This is an API reference with partial transport recipes. Values such as `p`, `input_data`, and the asynchronous target entry come from the surrounding application. ## Loading `payload` is a global namespace and does not require `require()`. ```lua payload.new(...) -- direct access ``` ## Format Constants The following constants identify payload formats: ```lua payload.format.JSON -- "json/plain" payload.format.YAML -- "yaml/plain" payload.format.STRING -- "text/plain" payload.format.BYTES -- "application/octet-stream" payload.format.MSGPACK -- "application/msgpack" payload.format.LUA -- "lua/any" payload.format.GOLANG -- "golang/any" payload.format.ERROR -- "golang/error" ``` ## Creating Payloads Create a payload from a Lua value: ```lua -- From table local p = payload.new({ user_id = 123, name = "Alice", roles = {"admin", "user"} }) -- From string local str_p = payload.new("Hello, World!") -- From number local num_p = payload.new(42.5) -- From boolean local bool_p = payload.new(true) -- From nil local nil_p = payload.new(nil) -- From error local err_p = payload.new(errors.new("something failed")) ``` | Parameter | Type | Description | |-----------|------|-------------| | `value` | any | Lua value (string, number, boolean, table, nil, or error) | **Returns:** `Payload` ## Getting Format Read the payload's format identifier: ```lua local p = payload.new({name = "test"}) local format = p:get_format() -- "lua/any" local str_p = payload.new("hello") local format2 = str_p:get_format() -- "lua/any" local err_p = payload.new(errors.new("failed")) local format3 = err_p:get_format() -- "golang/error" ``` **Returns:** `string` - one of `payload.format.*` constants ## Extracting Data Extract the payload's Lua value, transcoding when needed: ```lua local p = payload.new({ items = {1, 2, 3}, total = 100 }) local data, err = p:data() if err then return nil, err end print(data.total) -- 100 print(data.items[1]) -- 1 ``` **Returns:** `any, error` ## Transcoding Payloads Transcode a payload to another supported format: ```lua local p = payload.new({ name = "test", value = 123 }) -- Convert to JSON local json_p, err = p:transcode(payload.format.JSON) if err then return nil, err end print(json_p:get_format()) -- "json/plain" -- Convert to MessagePack (compact binary) local msgpack_p, err = p:transcode(payload.format.MSGPACK) if err then return nil, err end -- Convert to YAML local yaml_p, yaml_err = p:transcode(payload.format.YAML) if yaml_err then return nil, yaml_err end ``` | Parameter | Type | Description | |-----------|------|-------------| | `format` | string | Target format from `payload.format.*` | **Returns:** `Payload, error` ## Unmarshalling Decode a payload to a Lua value regardless of its source format: ```lua local data, err = p:unmarshal() if err then return nil, err end ``` `unmarshal()` behaves like `data()`: both transcode non-Lua payloads to the Lua format and return the resulting Lua value. The only difference is that `unmarshal()` returns an error when the transcoded data is not a valid Lua value, whereas `data()` returns `nil`. **Returns:** `any, error` ## Async Results Asynchronous function calls return their values in payloads: This example assumes `app.process:compute` returns exactly one value. With no result, `future:result()` returns `nil`; with multiple results, it returns a Lua table rather than one `Payload`, so callers must handle those shapes separately. ```lua local funcs = require("funcs") local future, err = funcs.async("app.process:compute", input_data) if err then return nil, err end -- Wait for result local ch = future:response() local _, ok = ch:receive() if not ok then return nil, errors.new("channel closed") end local result_payload, result_err = future:result() if result_err then return nil, result_err end if result_payload == nil then return nil, errors.new("compute returned no result") end -- Extract data from payload local result, err = result_payload:data() if err then return nil, err end print(result.computed_value) ``` ## Errors | Condition | Kind | Retryable | |-----------|------|-----------| | Transcoding failure | `errors.INTERNAL` | no | | Result not valid Lua value | `errors.INTERNAL` | no | See [Error Handling](lua/core/errors.md) for working with errors. ## Navigation Previous: "Archive" (lua/data/archive) Next: "Excel Spreadsheets" (lua/data/excel)