Sharing a javascript file, across policies that are used in multiple distinct shared flows

Hi All,

I have two shared flows SF1 and SF2 and shared flow SF1 has Javascript SF1-JS1.js and shared flow SF2 has SF2-JS2.js respectively.

Now I want to use the some funtion which is present in SF1-JS1 in SF2-JS2.

Is it possible to access javascript from one shared flow to another?

Solved Solved
1 3 1,428
1 ACCEPTED SOLUTION

It is possible to load JS as a resource into your environment, and refer to the JS code in any JS policy, whether than policy is in an apiproxy, or in a sharedflow.

Let's take a step back and look at the policy config:

<Javascript name='JS-1' timeLimit='200' >
  <IncludeURL>jsc://sharedResource1.js</IncludeURL>
  <IncludeURL>jsc://sharedResource2.js</IncludeURL>
  <ResourceURL>jsc://mainScript.js</ResourceURL>
</Javascript

Every Javascript policy must include a ResourceURL element. Optionally, the policy config can include one or more IncludeURL elements.

Actually there is no semantic difference between the JS files references with IncludeURL and ResourceURL. In fact, the way it works is Apigee Edge concatenates these JS files, in the order in which they are referred in the configuration, and then compiles the result.

Now, how does Apigee Edge satisfy the reference like "jsc://foo.js" ? Those strings denote resource references. And the resource itself can be attached to :

  • the API proxy
  • the environment

Apigee Edge will search those places in that order, in order to satisfy the reference.

So what you can do is include a module like "sharedmodule1.js" as a organization-wide resource. Then any JS policy in any environment will be able to use an IncludeURL that references that JS resource.

ok, HOW? How do you get that JS module registered as an organization resource? There is no way to do it using the Apigee Edge Administrative UI today. Instead you can use the Administrative API to register such resources.

# query available resources in an organization

$ curl -i -n $mgmtserver/v1/o/$orgname/e/test/resources/jsc
HTTP/1.1 200 OK
Access-Control-Allow-Headers: origin, x-requested-with, accept
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3628800
Content-Type: application/json
Date: Thu, 15 Feb 2018 23:25:33 GMT
Server: Apigee LB
Vary: Accept-Encoding, User-Agent
Content-Length: 44
Connection: keep-alive


[ "test.js", "jsrsasign-latest-all-min.js" ]

# retrieve one specific resource
 
$ curl -i -n $mgmtserver/v1/o/$orgname/e/test/resources/jsc/test.js
HTTP/1.1 200 OK
Access-Control-Allow-Headers: origin, x-requested-with, accept
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3628800
Content-Disposition: attachment; filename="Attachment"
Content-Type: application/octet-stream
Date: Thu, 15 Feb 2018 23:27:50 GMT
Server: Apigee LB
Content-Length: 36
Connection: keep-alive


context.setVariable('hello','world')


# update a resource in an environment:

curl -i -n -X PUT -H content-type:application/octet-stream \
  $mgmtserver/v1/o/$orgname/e/test/resources/jsc/test.js \
  -d 'context.setVariable("Hello", "World!"); context.setVariable("Hola", "Mundo!");'

Be aware, when using the UI to configure a JS policy for a particular proxy or Sharedflow, the environment-scoped resources, if any exist, are not shown in the dropdown .There's an outstanding feature request to add this. It's in the backlog.

6462-no-env-scoped-resources.png

Finally, If you use IncludeURL to refer to a JS source file, then I recommend taking care to modularize your JS code with something like an immediately-invoked function expression (IIFE). You can read more about this approach here.

View solution in original post

3 REPLIES 3

It is possible to load JS as a resource into your environment, and refer to the JS code in any JS policy, whether than policy is in an apiproxy, or in a sharedflow.

Let's take a step back and look at the policy config:

<Javascript name='JS-1' timeLimit='200' >
  <IncludeURL>jsc://sharedResource1.js</IncludeURL>
  <IncludeURL>jsc://sharedResource2.js</IncludeURL>
  <ResourceURL>jsc://mainScript.js</ResourceURL>
</Javascript

Every Javascript policy must include a ResourceURL element. Optionally, the policy config can include one or more IncludeURL elements.

Actually there is no semantic difference between the JS files references with IncludeURL and ResourceURL. In fact, the way it works is Apigee Edge concatenates these JS files, in the order in which they are referred in the configuration, and then compiles the result.

Now, how does Apigee Edge satisfy the reference like "jsc://foo.js" ? Those strings denote resource references. And the resource itself can be attached to :

  • the API proxy
  • the environment

Apigee Edge will search those places in that order, in order to satisfy the reference.

So what you can do is include a module like "sharedmodule1.js" as a organization-wide resource. Then any JS policy in any environment will be able to use an IncludeURL that references that JS resource.

ok, HOW? How do you get that JS module registered as an organization resource? There is no way to do it using the Apigee Edge Administrative UI today. Instead you can use the Administrative API to register such resources.

# query available resources in an organization

$ curl -i -n $mgmtserver/v1/o/$orgname/e/test/resources/jsc
HTTP/1.1 200 OK
Access-Control-Allow-Headers: origin, x-requested-with, accept
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3628800
Content-Type: application/json
Date: Thu, 15 Feb 2018 23:25:33 GMT
Server: Apigee LB
Vary: Accept-Encoding, User-Agent
Content-Length: 44
Connection: keep-alive


[ "test.js", "jsrsasign-latest-all-min.js" ]

# retrieve one specific resource
 
$ curl -i -n $mgmtserver/v1/o/$orgname/e/test/resources/jsc/test.js
HTTP/1.1 200 OK
Access-Control-Allow-Headers: origin, x-requested-with, accept
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3628800
Content-Disposition: attachment; filename="Attachment"
Content-Type: application/octet-stream
Date: Thu, 15 Feb 2018 23:27:50 GMT
Server: Apigee LB
Content-Length: 36
Connection: keep-alive


context.setVariable('hello','world')


# update a resource in an environment:

curl -i -n -X PUT -H content-type:application/octet-stream \
  $mgmtserver/v1/o/$orgname/e/test/resources/jsc/test.js \
  -d 'context.setVariable("Hello", "World!"); context.setVariable("Hola", "Mundo!");'

Be aware, when using the UI to configure a JS policy for a particular proxy or Sharedflow, the environment-scoped resources, if any exist, are not shown in the dropdown .There's an outstanding feature request to add this. It's in the backlog.

6462-no-env-scoped-resources.png

Finally, If you use IncludeURL to refer to a JS source file, then I recommend taking care to modularize your JS code with something like an immediately-invoked function expression (IIFE). You can read more about this approach here.

Thanks for this answer @Dino. I've managed to include a proxy-scoped javascript resource in different Javascript policies within the proxy. Works like a charm.

I understand that a JS resource can be attached to an organisation through the Management API, but I'd rather not go that path as the JS is not visible and can't be examined or edited by anyone who wants to use it.

So I thought I'd try to include a javascript resource using a Shared Flow as a wrapper to bring into the proxy. When I save the proxy, Apigee complains that the resource doesn't exist.

I've also tried running the Shared Flow through a Flow Callout, and that doesn't export the javascript module either.

Is there any way I can achieve this?

Any advice would be much appreciated.

Thank you.

a Javascript policy in the API Proxy cannot "see" a JS resource that is attached to a sharedflow. A Javascript policy in the API Proxy can "see" and resolve JS resources in the API Proxy, or in the environment, or in the organization**.

A Javascript policy in a sharedflow can "see" JS resources in the sharedflow, or in the environment, or in the organization **.

**In Apigee X, you cannot store such resources at the organization scope!