This post is about "how you can pick the first value you find from 2 objects" in Rego, a query language used in OPA (Open Policy Agent).
This use case is a little confusing and you'll probably think "When is this necessary?". One example is shared in "Merge Objects" in the official docs.
When merging multiple objects, you'll definitely need to think about colliding keys and how to decide which key
, value
to choose. This is where you'll want to use "Pick the first value you find from 2 objects".
Let's dive into details.
Logical OR in Rego
The function which "Picks the first value it finds from 2 objects" will be called pick_first
. Here's how the implementation will look like.
has_key(x, k) {
_ := x[k]
}
pick_first(k, a, b) = a[k]
pick_first(k, a, b) = b[k] { not has_key(a, k) }
See how there are 2 definitions of pick_first(k, a, b)
. This is how you express a Logical OR in Rego. So the expression above is like saying:
"For key k
, choose the value from object a
, OR, choose the value from object b
if object a
DOES NOT HAVE key k
."
If you feel uncomfortable with the has_key
function, look at my previous post specifically explaining about it here:
Check if key exists in object in Rego
Ken Fukuyama ・ Sep 28 '19 ・ 2 min read
Example
Here's a complete example demonstrating the usage of pick_first
.
has_key(x, k) {
_ := x[k]
}
pick_first(k, a, b) = a[k]
pick_first(k, a, b) = b[k] { not has_key(a, k) }
x := {"a": true, "b": false}
y := {"b": "foo", "c": 4}
first_values = fv {
a := pick_first("a", x, y)
b := pick_first("b", x, y)
c := pick_first("c", x, y)
fv := {
"a": a,
"b": b,
"c": c
}
}
If you evaluate first_values
, the result would be:
{
"a": true,
"b": false,
"c": 4
}
Notice how key false
was chosen from object x
's key b
. The only time the values of object y
are selected are when the key doesn't exist in object x
(e.g. key c
).
You can check this out for yourself in the following playground:
https://play.openpolicyagent.org/p/puwMTreKjD
Top comments (0)