HTTP and JSON Built-ins

L4 provides built-in functions for HTTP requests and JSON serialization. These enable integration with external APIs and data interchange.

HTTP Functions

FETCH

Performs an HTTP GET request.

Signature: STRING → STRING

Parameters:

  • url - The URL to fetch

Returns: Response body as a STRING

Example:

-- HTTP and JSON Built-in Examples
-- Demonstrates FETCH, POST, ENV, JSONENCODE, and JSONDECODE

--------------------------------------------------------------------------------
-- Record type for examples
--------------------------------------------------------------------------------

DECLARE Person HAS
  name IS A STRING
  age IS A NUMBER

--------------------------------------------------------------------------------
-- JSONENCODE Examples
--------------------------------------------------------------------------------

-- Encode a simple record
DECIDE alice IS Person WITH name IS "Alice", age IS 30
DECIDE aliceJson IS JSONENCODE alice
#EVAL aliceJson  -- {"name":"Alice","age":30}

-- Encode a list
DECIDE numbers IS LIST 1, 2, 3, 4, 5
DECIDE numbersJson IS JSONENCODE numbers
#EVAL numbersJson  -- [1,2,3,4,5]

-- Encode nested structures
DECLARE Team HAS
  teamName IS A STRING
  members IS A LIST OF Person

DECIDE bob IS Person WITH name IS "Bob", age IS 25

DECIDE team IS Team WITH
  teamName IS "Engineering"
  members IS LIST alice, bob

DECIDE teamJson IS JSONENCODE team
#EVAL teamJson

-- Encode MAYBE values
DECIDE justValue IS JSONENCODE (JUST 42)
#EVAL justValue  -- 42

DECIDE nothingValue IS JSONENCODE NOTHING
#EVAL nothingValue  -- null

--------------------------------------------------------------------------------
-- JSONDECODE Examples
--------------------------------------------------------------------------------





-- Decode JSON primitives - returns EITHER STRING value
DECIDE decodeString IS JSONDECODE "\"hello\""
DECIDE decodeNumber IS JSONDECODE "42"
DECIDE decodeArray IS JSONDECODE "[1, 2, 3]"






#EVAL decodeString   -- RIGHT "hello"
#EVAL decodeNumber   -- RIGHT 42
#EVAL decodeArray    -- RIGHT (LIST 1, 2, 3)


-- Decode a JSON object (returns generic object)
DECIDE decodeObject IS JSONDECODE "{\"name\":\"Charlie\",\"age\":28}"
#EVAL decodeObject




-- Pattern match to extract values from EITHER
DECIDE extractedValue IS
  CONSIDER decodeNumber
  WHEN RIGHT n THEN n
  WHEN LEFT err THEN 0


#EVAL extractedValue  -- 42

-- Handle decode errors gracefully


DECIDE badDecodeResult IS JSONDECODE "not valid json"

DECIDE handleError IS
  CONSIDER badDecodeResult

  WHEN RIGHT val THEN "Success"
  WHEN LEFT err THEN CONCAT "Error: ", err

#EVAL handleError  -- "Error: ..."

--------------------------------------------------------------------------------
-- ENV Examples (conceptual - requires environment variables to be set)
--------------------------------------------------------------------------------

-- Read an environment variable
-- DECIDE apiKey IS ENV "API_KEY"

-- Use in conditional logic
-- DECIDE hasApiKey IS NOT (apiKey EQUALS "")

--------------------------------------------------------------------------------
-- FETCH Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- Simple GET request
-- DECIDE uuid IS FETCH "https://www.uuidtools.com/api/generate/v4"

-- Fetch and decode JSON
-- ASSUME userData IS A EITHER STRING Person
-- DECIDE userData IS JSONDECODE (FETCH "https://api.example.com/user/1")

--------------------------------------------------------------------------------
-- POST Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- POST with JSON body
-- DECIDE response IS POST
--   "https://api.example.com/users"
--   "{\"Content-Type\": \"application/json\"}"
--   (JSONENCODE (Person WITH name IS "New User", age IS 21))

--------------------------------------------------------------------------------
-- Combined Pattern: Safe API Call with Fallback
--------------------------------------------------------------------------------

GIVEN jsonStr IS A STRING
      fallback IS A Person
GIVETH A Person
`safe decode person` jsonStr fallback MEANS
  CONSIDER JSONDECODE jsonStr
  WHEN RIGHT p THEN p
  WHEN LEFT err THEN fallback

DECIDE defaultPerson IS Person WITH name IS "Default", age IS 0
DECIDE result IS `safe decode person` "{\"name\":\"Test\",\"age\":99}" defaultPerson

#EVAL result's name  -- "Test"
-- Fetch data from an API
DECIDE uuid IS FETCH "https://www.uuidtools.com/api/generate/v4"

Note: FETCH is evaluated lazily. Multiple references to the same FETCH call return the same cached result.


POST

Performs an HTTP POST request.

Signature: STRING → STRING → STRING → STRING

Parameters:

  • url - The URL to post to
  • headers - HTTP headers as a JSON string (e.g., "{\"Content-Type\": \"application/json\"}")
  • body - Request body as a STRING

Returns: Response body as a STRING

Example:

-- HTTP and JSON Built-in Examples
-- Demonstrates FETCH, POST, ENV, JSONENCODE, and JSONDECODE

--------------------------------------------------------------------------------
-- Record type for examples
--------------------------------------------------------------------------------

DECLARE Person HAS
  name IS A STRING
  age IS A NUMBER

--------------------------------------------------------------------------------
-- JSONENCODE Examples
--------------------------------------------------------------------------------

-- Encode a simple record
DECIDE alice IS Person WITH name IS "Alice", age IS 30
DECIDE aliceJson IS JSONENCODE alice
#EVAL aliceJson  -- {"name":"Alice","age":30}

-- Encode a list
DECIDE numbers IS LIST 1, 2, 3, 4, 5
DECIDE numbersJson IS JSONENCODE numbers
#EVAL numbersJson  -- [1,2,3,4,5]

-- Encode nested structures
DECLARE Team HAS
  teamName IS A STRING
  members IS A LIST OF Person

DECIDE bob IS Person WITH name IS "Bob", age IS 25

DECIDE team IS Team WITH
  teamName IS "Engineering"
  members IS LIST alice, bob

DECIDE teamJson IS JSONENCODE team
#EVAL teamJson

-- Encode MAYBE values
DECIDE justValue IS JSONENCODE (JUST 42)
#EVAL justValue  -- 42

DECIDE nothingValue IS JSONENCODE NOTHING
#EVAL nothingValue  -- null

--------------------------------------------------------------------------------
-- JSONDECODE Examples
--------------------------------------------------------------------------------





-- Decode JSON primitives - returns EITHER STRING value
DECIDE decodeString IS JSONDECODE "\"hello\""
DECIDE decodeNumber IS JSONDECODE "42"
DECIDE decodeArray IS JSONDECODE "[1, 2, 3]"






#EVAL decodeString   -- RIGHT "hello"
#EVAL decodeNumber   -- RIGHT 42
#EVAL decodeArray    -- RIGHT (LIST 1, 2, 3)


-- Decode a JSON object (returns generic object)
DECIDE decodeObject IS JSONDECODE "{\"name\":\"Charlie\",\"age\":28}"
#EVAL decodeObject




-- Pattern match to extract values from EITHER
DECIDE extractedValue IS
  CONSIDER decodeNumber
  WHEN RIGHT n THEN n
  WHEN LEFT err THEN 0


#EVAL extractedValue  -- 42

-- Handle decode errors gracefully


DECIDE badDecodeResult IS JSONDECODE "not valid json"

DECIDE handleError IS
  CONSIDER badDecodeResult

  WHEN RIGHT val THEN "Success"
  WHEN LEFT err THEN CONCAT "Error: ", err

#EVAL handleError  -- "Error: ..."

--------------------------------------------------------------------------------
-- ENV Examples (conceptual - requires environment variables to be set)
--------------------------------------------------------------------------------

-- Read an environment variable
-- DECIDE apiKey IS ENV "API_KEY"

-- Use in conditional logic
-- DECIDE hasApiKey IS NOT (apiKey EQUALS "")

--------------------------------------------------------------------------------
-- FETCH Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- Simple GET request
-- DECIDE uuid IS FETCH "https://www.uuidtools.com/api/generate/v4"

-- Fetch and decode JSON
-- ASSUME userData IS A EITHER STRING Person
-- DECIDE userData IS JSONDECODE (FETCH "https://api.example.com/user/1")

--------------------------------------------------------------------------------
-- POST Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- POST with JSON body
-- DECIDE response IS POST
--   "https://api.example.com/users"
--   "{\"Content-Type\": \"application/json\"}"
--   (JSONENCODE (Person WITH name IS "New User", age IS 21))

--------------------------------------------------------------------------------
-- Combined Pattern: Safe API Call with Fallback
--------------------------------------------------------------------------------

GIVEN jsonStr IS A STRING
      fallback IS A Person
GIVETH A Person
`safe decode person` jsonStr fallback MEANS
  CONSIDER JSONDECODE jsonStr
  WHEN RIGHT p THEN p
  WHEN LEFT err THEN fallback

DECIDE defaultPerson IS Person WITH name IS "Default", age IS 0
DECIDE result IS `safe decode person` "{\"name\":\"Test\",\"age\":99}" defaultPerson

#EVAL result's name  -- "Test"
-- Post JSON to an API
DECIDE response IS POST
  "https://api.example.com/data"
  "{\"Content-Type\": \"application/json\"}"
  "{\"name\": \"test\"}"

ENV

Reads an environment variable.

Signature: STRING → STRING

Parameters:

  • name - The environment variable name

Returns: The value of the environment variable, or empty string if not set

Example:

-- HTTP and JSON Built-in Examples
-- Demonstrates FETCH, POST, ENV, JSONENCODE, and JSONDECODE

--------------------------------------------------------------------------------
-- Record type for examples
--------------------------------------------------------------------------------

DECLARE Person HAS
  name IS A STRING
  age IS A NUMBER

--------------------------------------------------------------------------------
-- JSONENCODE Examples
--------------------------------------------------------------------------------

-- Encode a simple record
DECIDE alice IS Person WITH name IS "Alice", age IS 30
DECIDE aliceJson IS JSONENCODE alice
#EVAL aliceJson  -- {"name":"Alice","age":30}

-- Encode a list
DECIDE numbers IS LIST 1, 2, 3, 4, 5
DECIDE numbersJson IS JSONENCODE numbers
#EVAL numbersJson  -- [1,2,3,4,5]

-- Encode nested structures
DECLARE Team HAS
  teamName IS A STRING
  members IS A LIST OF Person

DECIDE bob IS Person WITH name IS "Bob", age IS 25

DECIDE team IS Team WITH
  teamName IS "Engineering"
  members IS LIST alice, bob

DECIDE teamJson IS JSONENCODE team
#EVAL teamJson

-- Encode MAYBE values
DECIDE justValue IS JSONENCODE (JUST 42)
#EVAL justValue  -- 42

DECIDE nothingValue IS JSONENCODE NOTHING
#EVAL nothingValue  -- null

--------------------------------------------------------------------------------
-- JSONDECODE Examples
--------------------------------------------------------------------------------





-- Decode JSON primitives - returns EITHER STRING value
DECIDE decodeString IS JSONDECODE "\"hello\""
DECIDE decodeNumber IS JSONDECODE "42"
DECIDE decodeArray IS JSONDECODE "[1, 2, 3]"






#EVAL decodeString   -- RIGHT "hello"
#EVAL decodeNumber   -- RIGHT 42
#EVAL decodeArray    -- RIGHT (LIST 1, 2, 3)


-- Decode a JSON object (returns generic object)
DECIDE decodeObject IS JSONDECODE "{\"name\":\"Charlie\",\"age\":28}"
#EVAL decodeObject




-- Pattern match to extract values from EITHER
DECIDE extractedValue IS
  CONSIDER decodeNumber
  WHEN RIGHT n THEN n
  WHEN LEFT err THEN 0


#EVAL extractedValue  -- 42

-- Handle decode errors gracefully


DECIDE badDecodeResult IS JSONDECODE "not valid json"

DECIDE handleError IS
  CONSIDER badDecodeResult

  WHEN RIGHT val THEN "Success"
  WHEN LEFT err THEN CONCAT "Error: ", err

#EVAL handleError  -- "Error: ..."

--------------------------------------------------------------------------------
-- ENV Examples (conceptual - requires environment variables to be set)
--------------------------------------------------------------------------------

-- Read an environment variable
-- DECIDE apiKey IS ENV "API_KEY"

-- Use in conditional logic
-- DECIDE hasApiKey IS NOT (apiKey EQUALS "")

--------------------------------------------------------------------------------
-- FETCH Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- Simple GET request
-- DECIDE uuid IS FETCH "https://www.uuidtools.com/api/generate/v4"

-- Fetch and decode JSON
-- ASSUME userData IS A EITHER STRING Person
-- DECIDE userData IS JSONDECODE (FETCH "https://api.example.com/user/1")

--------------------------------------------------------------------------------
-- POST Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- POST with JSON body
-- DECIDE response IS POST
--   "https://api.example.com/users"
--   "{\"Content-Type\": \"application/json\"}"
--   (JSONENCODE (Person WITH name IS "New User", age IS 21))

--------------------------------------------------------------------------------
-- Combined Pattern: Safe API Call with Fallback
--------------------------------------------------------------------------------

GIVEN jsonStr IS A STRING
      fallback IS A Person
GIVETH A Person
`safe decode person` jsonStr fallback MEANS
  CONSIDER JSONDECODE jsonStr
  WHEN RIGHT p THEN p
  WHEN LEFT err THEN fallback

DECIDE defaultPerson IS Person WITH name IS "Default", age IS 0
DECIDE result IS `safe decode person` "{\"name\":\"Test\",\"age\":99}" defaultPerson

#EVAL result's name  -- "Test"
-- Read API key from environment
DECIDE apiKey IS ENV "API_KEY"

Security Note: Use ENV to keep sensitive values like API keys out of source code.


JSON Functions

JSONENCODE

Converts an L4 value to its JSON string representation.

Signature: a → STRING (polymorphic)

Behavior:

  • Numbers render as JSON numbers
  • Strings render as JSON strings (with escaping)
  • Booleans render as true or false
  • Lists render as JSON arrays
  • Records render as JSON objects
  • NOTHING renders as null
  • JUST x renders as the encoding of x
  • Enum constructors render as JSON objects with constructor name

Example:

-- HTTP and JSON Built-in Examples
-- Demonstrates FETCH, POST, ENV, JSONENCODE, and JSONDECODE

--------------------------------------------------------------------------------
-- Record type for examples
--------------------------------------------------------------------------------

DECLARE Person HAS
  name IS A STRING
  age IS A NUMBER

--------------------------------------------------------------------------------
-- JSONENCODE Examples
--------------------------------------------------------------------------------

-- Encode a simple record
DECIDE alice IS Person WITH name IS "Alice", age IS 30
DECIDE aliceJson IS JSONENCODE alice
#EVAL aliceJson  -- {"name":"Alice","age":30}

-- Encode a list
DECIDE numbers IS LIST 1, 2, 3, 4, 5
DECIDE numbersJson IS JSONENCODE numbers
#EVAL numbersJson  -- [1,2,3,4,5]

-- Encode nested structures
DECLARE Team HAS
  teamName IS A STRING
  members IS A LIST OF Person

DECIDE bob IS Person WITH name IS "Bob", age IS 25

DECIDE team IS Team WITH
  teamName IS "Engineering"
  members IS LIST alice, bob

DECIDE teamJson IS JSONENCODE team
#EVAL teamJson

-- Encode MAYBE values
DECIDE justValue IS JSONENCODE (JUST 42)
#EVAL justValue  -- 42

DECIDE nothingValue IS JSONENCODE NOTHING
#EVAL nothingValue  -- null

--------------------------------------------------------------------------------
-- JSONDECODE Examples
--------------------------------------------------------------------------------





-- Decode JSON primitives - returns EITHER STRING value
DECIDE decodeString IS JSONDECODE "\"hello\""
DECIDE decodeNumber IS JSONDECODE "42"
DECIDE decodeArray IS JSONDECODE "[1, 2, 3]"






#EVAL decodeString   -- RIGHT "hello"
#EVAL decodeNumber   -- RIGHT 42
#EVAL decodeArray    -- RIGHT (LIST 1, 2, 3)


-- Decode a JSON object (returns generic object)
DECIDE decodeObject IS JSONDECODE "{\"name\":\"Charlie\",\"age\":28}"
#EVAL decodeObject




-- Pattern match to extract values from EITHER
DECIDE extractedValue IS
  CONSIDER decodeNumber
  WHEN RIGHT n THEN n
  WHEN LEFT err THEN 0


#EVAL extractedValue  -- 42

-- Handle decode errors gracefully


DECIDE badDecodeResult IS JSONDECODE "not valid json"

DECIDE handleError IS
  CONSIDER badDecodeResult

  WHEN RIGHT val THEN "Success"
  WHEN LEFT err THEN CONCAT "Error: ", err

#EVAL handleError  -- "Error: ..."

--------------------------------------------------------------------------------
-- ENV Examples (conceptual - requires environment variables to be set)
--------------------------------------------------------------------------------

-- Read an environment variable
-- DECIDE apiKey IS ENV "API_KEY"

-- Use in conditional logic
-- DECIDE hasApiKey IS NOT (apiKey EQUALS "")

--------------------------------------------------------------------------------
-- FETCH Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- Simple GET request
-- DECIDE uuid IS FETCH "https://www.uuidtools.com/api/generate/v4"

-- Fetch and decode JSON
-- ASSUME userData IS A EITHER STRING Person
-- DECIDE userData IS JSONDECODE (FETCH "https://api.example.com/user/1")

--------------------------------------------------------------------------------
-- POST Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- POST with JSON body
-- DECIDE response IS POST
--   "https://api.example.com/users"
--   "{\"Content-Type\": \"application/json\"}"
--   (JSONENCODE (Person WITH name IS "New User", age IS 21))

--------------------------------------------------------------------------------
-- Combined Pattern: Safe API Call with Fallback
--------------------------------------------------------------------------------

GIVEN jsonStr IS A STRING
      fallback IS A Person
GIVETH A Person
`safe decode person` jsonStr fallback MEANS
  CONSIDER JSONDECODE jsonStr
  WHEN RIGHT p THEN p
  WHEN LEFT err THEN fallback

DECIDE defaultPerson IS Person WITH name IS "Default", age IS 0
DECIDE result IS `safe decode person` "{\"name\":\"Test\",\"age\":99}" defaultPerson

#EVAL result's name  -- "Test"
DECLARE Person HAS
  name IS A STRING
  age IS A NUMBER

DECIDE alice IS Person WITH name IS "Alice", age IS 30

-- Produces: {"name":"Alice","age":30}
DECIDE aliceJson IS JSONENCODE alice

JSONDECODE

Parses a JSON string into an L4 value.

Signature: STRING → EITHER STRING a (polymorphic)

Returns:

  • RIGHT value on successful parse
  • LEFT errorMessage on parse failure

Behavior:

  • JSON objects decode to records (field names must match)
  • JSON arrays decode to lists
  • JSON numbers decode to NUMBER
  • JSON strings decode to STRING
  • JSON booleans decode to BOOLEAN
  • JSON null decodes to NOTHING (for MAYBE types)

Example:

-- HTTP and JSON Built-in Examples
-- Demonstrates FETCH, POST, ENV, JSONENCODE, and JSONDECODE

--------------------------------------------------------------------------------
-- Record type for examples
--------------------------------------------------------------------------------

DECLARE Person HAS
  name IS A STRING
  age IS A NUMBER

--------------------------------------------------------------------------------
-- JSONENCODE Examples
--------------------------------------------------------------------------------

-- Encode a simple record
DECIDE alice IS Person WITH name IS "Alice", age IS 30
DECIDE aliceJson IS JSONENCODE alice
#EVAL aliceJson  -- {"name":"Alice","age":30}

-- Encode a list
DECIDE numbers IS LIST 1, 2, 3, 4, 5
DECIDE numbersJson IS JSONENCODE numbers
#EVAL numbersJson  -- [1,2,3,4,5]

-- Encode nested structures
DECLARE Team HAS
  teamName IS A STRING
  members IS A LIST OF Person

DECIDE bob IS Person WITH name IS "Bob", age IS 25

DECIDE team IS Team WITH
  teamName IS "Engineering"
  members IS LIST alice, bob

DECIDE teamJson IS JSONENCODE team
#EVAL teamJson

-- Encode MAYBE values
DECIDE justValue IS JSONENCODE (JUST 42)
#EVAL justValue  -- 42

DECIDE nothingValue IS JSONENCODE NOTHING
#EVAL nothingValue  -- null

--------------------------------------------------------------------------------
-- JSONDECODE Examples
--------------------------------------------------------------------------------





-- Decode JSON primitives - returns EITHER STRING value
DECIDE decodeString IS JSONDECODE "\"hello\""
DECIDE decodeNumber IS JSONDECODE "42"
DECIDE decodeArray IS JSONDECODE "[1, 2, 3]"






#EVAL decodeString   -- RIGHT "hello"
#EVAL decodeNumber   -- RIGHT 42
#EVAL decodeArray    -- RIGHT (LIST 1, 2, 3)


-- Decode a JSON object (returns generic object)
DECIDE decodeObject IS JSONDECODE "{\"name\":\"Charlie\",\"age\":28}"
#EVAL decodeObject




-- Pattern match to extract values from EITHER
DECIDE extractedValue IS
  CONSIDER decodeNumber
  WHEN RIGHT n THEN n
  WHEN LEFT err THEN 0


#EVAL extractedValue  -- 42

-- Handle decode errors gracefully


DECIDE badDecodeResult IS JSONDECODE "not valid json"

DECIDE handleError IS
  CONSIDER badDecodeResult

  WHEN RIGHT val THEN "Success"
  WHEN LEFT err THEN CONCAT "Error: ", err

#EVAL handleError  -- "Error: ..."

--------------------------------------------------------------------------------
-- ENV Examples (conceptual - requires environment variables to be set)
--------------------------------------------------------------------------------

-- Read an environment variable
-- DECIDE apiKey IS ENV "API_KEY"

-- Use in conditional logic
-- DECIDE hasApiKey IS NOT (apiKey EQUALS "")

--------------------------------------------------------------------------------
-- FETCH Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- Simple GET request
-- DECIDE uuid IS FETCH "https://www.uuidtools.com/api/generate/v4"

-- Fetch and decode JSON
-- ASSUME userData IS A EITHER STRING Person
-- DECIDE userData IS JSONDECODE (FETCH "https://api.example.com/user/1")

--------------------------------------------------------------------------------
-- POST Examples (conceptual - requires network access)
--------------------------------------------------------------------------------

-- POST with JSON body
-- DECIDE response IS POST
--   "https://api.example.com/users"
--   "{\"Content-Type\": \"application/json\"}"
--   (JSONENCODE (Person WITH name IS "New User", age IS 21))

--------------------------------------------------------------------------------
-- Combined Pattern: Safe API Call with Fallback
--------------------------------------------------------------------------------

GIVEN jsonStr IS A STRING
      fallback IS A Person
GIVETH A Person
`safe decode person` jsonStr fallback MEANS
  CONSIDER JSONDECODE jsonStr
  WHEN RIGHT p THEN p
  WHEN LEFT err THEN fallback

DECIDE defaultPerson IS Person WITH name IS "Default", age IS 0
DECIDE result IS `safe decode person` "{\"name\":\"Test\",\"age\":99}" defaultPerson

#EVAL result's name  -- "Test"
DECLARE Person HAS
  name IS A STRING
  age IS A NUMBER

-- Parse JSON into a Person record
DECIDE parsed IS JSONDECODE "{\"name\":\"Bob\",\"age\":25}"

-- Handle parse result
DECIDE person IS
  CONSIDER parsed
  WHEN RIGHT p THEN p
  WHEN LEFT err THEN Person WITH name IS "Unknown", age IS 0

Type Inference: JSONDECODE uses bidirectional type checking. The expected type guides parsing:

-- Type annotation guides decoding
ASSUME result IS A EITHER STRING Person
DECIDE result IS JSONDECODE jsonString

Common Patterns

API Integration

-- Fetch and parse JSON from an API
DECIDE fetchUser userId IS
  LET url IS CONCAT "https://api.example.com/users/", userId
  IN LET response IS FETCH url
     IN JSONDECODE response

Authenticated Requests

-- Use environment variable for API key
DECIDE callApi endpoint body IS
  LET apiKey IS ENV "API_KEY"
  IN LET headers IS CONCAT "{\"Authorization\": \"Bearer ", apiKey, "\"}"
     IN POST endpoint headers body

Error Handling

-- Safely decode with fallback
GIVEN jsonStr IS A STRING
GIVEN fallback IS A Person
GIVETH A Person
safeDecode jsonStr fallback MEANS
  CONSIDER JSONDECODE jsonStr
  WHEN RIGHT person THEN person
  WHEN LEFT _ THEN fallback

See Also