# FCALL_RO

> Invoke a read-only function

<Note>
  The function must be declared with the `no-writes` flag for it to be used with `callRo`.
</Note>

## Arguments

<ParamField body="function" type="string" required>
  The function name.
</ParamField>

<ParamField body="keys" type="string[]">
  The keys that the function accesses.

  <Warning>
    The function can only read from the keys that are provided in the `keys` argument.
  </Warning>
</ParamField>

<ParamField body="args" type="string[]">
  The arguments for the function.
</ParamField>

## Response

<ResponseField type="unknown" required>
  The return value of the function.
</ResponseField>

<RequestExample>
```ts Example
const code = `
#!lua name=ro_lib
  
local function get_value(keys, args)
  return redis.call('GET', keys[1])
end

redis.register_function({
  function_name='get_value', 
  callback=get_value, 
  flags={ 'no-writes' }
})
`;

await redis.functions.load({ code, replace: true });

// Call the read-only function
// Note: We can modify the keys usage here, but since it represents a read-only operation
// and we marked it with 'no-writes', it is safe to use callRo.
const value = await redis.functions.callRo("get_value", ["mykey"])
```
</RequestExample>
