Hi,
I have a task where someone sends a request to apigee with a key and a value for example Key: test, value:helloworld in the header and I need to hash the value and cache it before sending the request to the backend.
I've seen that this can be done using an AssignMessage policy but I havent a solution of how it can be done.
Any help on this would be much appreciated 🙂
Thanks in advance
How about this:?
<AssignMessage name='AM-HashValue'> <AssignVariable> <Name>hash_result</Name> <Template>{sha256Hex(request.header.something)}</Template> </AssignVariable> </AssignMessage>
Notes:
@Dino-at-Google Thanks for the quick response Dino, what is the extra step to normalize the value of the header?
By "normalize" maybe I should have said.... "canonicalize". And maybe you understand what I mean, but here's an illustration. Let's suppose the header is supposed to contain a JSON value. The client might pass this:
{ "key" : "value1" }
Notice there are spaces in there: between the open-curly and the first quote. before and after the colon. Before the close curly. The hex-encoded sha256 for that string, with all the spaces, according to this page, is
c870c19976aba77046667dc9b9986c73a8e4805c99186bc8ea6e7e56e5fe130b<br>
Now suppose the client eliminates spaces. The JSON is this:
{"key":"value1"}<br>
Semantically equal. This JSON represents the same information as the previous JSON. But the sha256 of the second string is
dfada72ccc2244e8c7aef8f0dbe7c026a6553bc5bda3f7654f3d0b94dd51a23b<br>
And obviously that's different. If you use the simple sha256 as the cache key, you will get two distinct cache entries for those inbound values. I think maybe you want a single cache entry, although it's possible you don't care either way.
if you want a single cache entry for each JSON that is semantically the same, you need to canonicalize the inbound json in order to get the same key.
"canonicalize": convert to a standard form, either with a standard amount of spaces, or with zero spaces... something like that. It doesn't matter, as long as you are consistent. For JSON it's pretty easy. Normalizing the value would require a JavaScript step, before the AssignMessage with code something like this:
var json = JSON.parse(context.getVariable('request.header.something')); var canonicalized = JSON.stringify(json); // a canonicalized json string context.setVariable('canonicalized'), canonicalized);
(JSON.stringify removes all the extraneous whitespaces.)
And then the AssignMessage would be
<AssignMessage name='AM-HashValue'> <AssignVariable> <Name>hash_result</Name> <Template>{sha256Hex(canonicalized)}</Template> </AssignVariable> </AssignMessage><br>