Redis Functions
Redis Functions¶
Redis Functions is an
evolution of the scripting API to provide extensibility beyond Lua.
Functions can leverage different engines and follow a model where a
function library registers functionality to be invoked later with the
FCALL
command.
Using Functions is straightforward. Consuming results in Java requires
additional details to consume the result through a matching type. As we
do not know what your function will return, the API uses call-site
generics for you to specify the result type. Additionally, you must
provide a ScriptOutputType
hint to EVAL
so that the driver uses the
appropriate output parser. See Output Formats for
further details.
Output Formats¶
You can choose from one of the following:
-
BOOLEAN
: Boolean output, expects a number0
or1
to be converted to a boolean value. -
INTEGER
: 64-bit Integer output, represented as JavaLong
. -
MULTI
: List of flat arrays. -
STATUS
: Simple status value such asOK
. The Redis response is parsed as ASCII. -
VALUE
: Value return type decoded throughRedisCodec
. -
OBJECT
: RESP3-defined object output supporting all Redis response structures.
Leveraging Scripting and Functions through Command Interfaces¶
Using dynamic functionality without a documented response structure can impose quite some complexity on your application. If you consider using scripting or functions, then you can use Command Interfaces to declare an interface along with methods that represent your scripting or function landscape. Declaring a method with input arguments and a response type not only makes it obvious how the script or function is supposed to be called, but also how the response structure should look like.
Let’s take a look at a simple function call first:
This example calls the my_hlastmodified
function expecting some Long
response an input argument. Calling a function from a single place in
your code isn’t an issue on its own. The arrangement becomes problematic
once the number of functions grows or you start calling the functions
with different arguments from various places in your code. Without the
function code, it becomes impossible to investigate how the response
mechanics work or determine the argument semantics, as there is no
single place to document the function behavior.
Let’s apply the Command Interface pattern to see how the the declaration and call sites change:
interface MyCustomCommands extends Commands {
/**
* Retrieve the last modified value from the hash key.
* @param hashKey the key of the hash.
* @return the last modified timestamp, can be {@code null}.
*/
@Command("FCALL my_hlastmodified 1 :hashKey")
Long getLastModified(@Param("my_hash") String hashKey);
}
MyCustomCommands myCommands = …;
Long lastModified = myCommands.getLastModified("my_hash");
By declaring a command method, you create a place that allows for storing additional documentation. The method declaration makes clear what the function call expects and what you get in return.