DEV Community

Cover image for What Are Environment Resources in Apigee X? A Beginner-Friendly Guide
realNameHidden
realNameHidden

Posted on

What Are Environment Resources in Apigee X? A Beginner-Friendly Guide

Learn what Environment Resources in Apigee X are, how they work, when to use them, and how to manage reusable JavaScript, Java, and config files.

Introduction

Imagine you have 20 API proxies running in your Apigee X environment.

Several of those proxies need the same JavaScript logic:

  • Validate a request
  • Modify a header
  • Generate a value
  • Transform data
  • Perform some reusable processing

You could copy the same JavaScript file into every API proxy.

But what happens when you need to change that logic?

You now have to update the same file in 20 different proxies.

That's difficult to maintain and easy to get wrong.

This is where Environment Resources in Apigee X become useful.

Instead of keeping a resource inside one API proxy, you can store it at the environment level and make it available to multiple API proxies deployed in that environment.

Think of an environment resource as a shared toolbox for your APIs.

One environment → shared resources → multiple API proxies

In this article, we'll understand:

  • What Environment Resources are
  • Why they are needed
  • Environment-level vs API-proxy-level resources
  • Supported resource types
  • How resource resolution works
  • How to create an Environment Resource
  • How an API proxy uses it
  • Practical use cases
  • Best practices
  • Common mistakes

By the end, you'll be able to explain Environment Resources confidently in both real-world projects and Apigee X interviews.

What Are Environment Resources in Apigee X?

An Environment Resource is a resource file stored at the Apigee environment level.

These resources can be used by API proxies deployed in that environment.

Google describes resources as files that implement code or configuration used by policies attached to API proxies. Environment-level resources are available to any API proxy deployed in that environment.

For example, suppose you have an Apigee environment called:

test
Enter fullscreen mode Exit fullscreen mode

You can store a JavaScript file:

validateRequest.js
Enter fullscreen mode Exit fullscreen mode

at the environment level.

Then multiple API proxies deployed in test can use it.

                    Apigee Organization
                           |
                    +------v------+
                    |     test    |
                    | Environment |
                    +------+------+
                           |
             +-------------+-------------+
             |             |             |
       Payment API     Order API      Customer API
             |             |             |
             +-------------+-------------+
                           |
                    validateRequest.js
                    Environment Resource
Enter fullscreen mode Exit fullscreen mode

The important idea is:

Environment Resources provide reusable files that can be shared by API proxies within the same environment.

Why Do We Need Environment Resources?

Let's take a simple example.

Suppose you have three API proxies:

Payment API
Order API
Customer API
Enter fullscreen mode Exit fullscreen mode

All three need this JavaScript logic:

request.headers["X-Request-Source"] = "Apigee";
Enter fullscreen mode Exit fullscreen mode

Without Environment Resources

You might have:

Payment API
 └── validate.js

Order API
 └── validate.js

Customer API
 └── validate.js
Enter fullscreen mode Exit fullscreen mode

Now you have three copies of the same logic.

If you change the logic, you have to update all three.

With Environment Resources

You can have:

test environment
│
└── Resources
    └── validate.js
Enter fullscreen mode Exit fullscreen mode

And:

Payment API ───────┐
Order API ─────────┼──> validate.js
Customer API ──────┘
Enter fullscreen mode Exit fullscreen mode

Much cleaner.

This gives you:

  • Reusability
  • Centralized maintenance
  • Less duplication
  • Easier deployment management
  • Consistent behavior across APIs

Environment Resources vs API Proxy Resources

This is one of the most important concepts to understand.

Apigee resources can be stored at different scopes.

The two important scopes are:

  1. API proxy revision
  2. Environment

According to Google's documentation, proxy-revision resources are available only to that particular API proxy revision, while environment-level resources are available to API proxies deployed in that environment. ([Google Cloud Documentation][1])

API Proxy Revision Resource

Imagine:

Payment API
   |
   └── Revision 3
        |
        └── validate.js
Enter fullscreen mode Exit fullscreen mode

Only that API proxy revision can use the resource.

Think of it as:

Private toolbox for one API proxy.

Environment Resource

Now imagine:

Test Environment
       |
       +── validate.js
       |
       +── common.js
       |
       +── transformation.xsl
Enter fullscreen mode Exit fullscreen mode

Multiple API proxies can access these resources.

Think of it as:

Shared toolbox for the entire environment.

Simple Analogy: Personal Toolbox vs Team Toolbox

Imagine you're working in a workshop.

API Proxy Resource

You have your own toolbox:

Your Toolbox
 ├── Hammer
 ├── Screwdriver
 └── Wrench
Enter fullscreen mode Exit fullscreen mode

Only you use it.

That's similar to a proxy-revision resource.

Environment Resource

The workshop has a common toolbox:

Workshop Toolbox
 ├── Drill
 ├── Measuring Tape
 └── Power Saw
Enter fullscreen mode Exit fullscreen mode

Multiple workers can use it.

That's similar to an environment-level resource.

What Types of Resources Can You Store?

Apigee supports several resource types.

Common resource types include:

Resource Type Extension / Type Typical Usage
JavaScript jsc Custom JavaScript logic
Java java JavaCallout JAR files
Python py Python-based processing where supported
Properties properties Configuration data
XSL xsl XML transformation
WSDL wsdl Web service definitions
XSD xsd XML schemas
JavaScript js Resource type supported by APIs/documentation

Google's current resource-file API documents resource types including java, js, jsc, properties, py, wsdl, xsd, and xsl.

A Very Important Point: Environment Resources Are Not KVMs

Beginners often confuse these concepts.

An Environment Resource is a file.

A KVM is a key-value data store.

For example:

Environment Resource

validateRequest.js
Enter fullscreen mode Exit fullscreen mode

contains:

var amount = context.getVariable("request.content.amount");

if (amount <= 0) {
    throw new Error("Invalid amount");
}
Enter fullscreen mode Exit fullscreen mode

KVM

backend.url = https://backend.example.com
timeout = 5000
Enter fullscreen mode Exit fullscreen mode

So:

Resource = file/code/config artifact

KVM = key-value configuration/data

Don't use an Environment Resource as a replacement for a KVM when you need runtime configuration values.

How Does an Environment Resource Work?

Let's look at the complete flow.

Suppose we have:

Client
   |
   v
Apigee X
   |
   v
Payment API Proxy
   |
   v
JavaScript Policy
   |
   v
validateRequest.js
   |
   v
Backend
Enter fullscreen mode Exit fullscreen mode

The JavaScript policy references the resource:

<Javascript name="ValidateRequest">
    <ResourceURL>jsc://validateRequest.js</ResourceURL>
</Javascript>
Enter fullscreen mode Exit fullscreen mode

The important part is:

jsc://validateRequest.js
Enter fullscreen mode Exit fullscreen mode

This tells Apigee:

"Find the JavaScript resource named validateRequest.js."

Resource Resolution in Apigee X

This is an important interview topic.

What happens if the same resource exists in multiple locations?

For example:

API Proxy Revision
       |
       └── validateRequest.js

Environment
       |
       └── validateRequest.js
Enter fullscreen mode Exit fullscreen mode

Which one does Apigee use?

Apigee resolves resource names from the most specific scope to the more general scope.

The resolution order is essentially:

API Proxy Revision
        ↓
Environment
Enter fullscreen mode Exit fullscreen mode

So the proxy-revision resource takes precedence over the environment-level resource when the same resource name exists at both scopes. ([Google Cloud Documentation][1])

Think of it like this:

Does proxy revision contain validateRequest.js?
                |
        +-------+-------+
       YES             NO
        |               |
        v               v
     Use it       Check Environment
                        |
                  +-----+-----+
                 YES          NO
                  |            |
                  v            v
              Use it       Resource not found
Enter fullscreen mode Exit fullscreen mode

This behavior is called resource name resolution.

Practical Example: Shared JavaScript Resource

Let's build a simple example.

Suppose three API proxies need to add a correlation ID.

Instead of implementing the same logic in every proxy, create:

generateCorrelationId.js
Enter fullscreen mode Exit fullscreen mode

The JavaScript could be:

var correlationId = context.getVariable("request.header.X-Correlation-ID");

if (!correlationId) {
    correlationId = String(java.util.UUID.randomUUID());
    context.setVariable("request.header.X-Correlation-ID", correlationId);
}
Enter fullscreen mode Exit fullscreen mode

Now store this file as an environment resource.

Multiple proxies can use it.

                 Test Environment
                       |
                       |
              generateCorrelationId.js
                       |
          +------------+------------+
          |            |            |
          v            v            v
      Payment API   Order API   Customer API
Enter fullscreen mode Exit fullscreen mode

This is a good example of reusable API management logic.

Step-by-Step: Create an Environment Resource

Let's see how you can create an environment-level resource using the Apigee X UI.

Step 1: Open Apigee

Open the Google Cloud Console and navigate to:

Apigee
   ↓
Admin / Management
   ↓
Environments
Enter fullscreen mode Exit fullscreen mode

Google's current documentation describes managing environment-level resources from the environment's Resources tab. ([Google Cloud Documentation][1])

Step 2: Select the Environment

Suppose you have:

test
prod
Enter fullscreen mode Exit fullscreen mode

Select:

test
Enter fullscreen mode Exit fullscreen mode

Remember:

An environment resource belongs to a specific environment.

So a resource stored in test isn't automatically available in prod.

Step 3: Open Resources

Navigate to the environment's:

Resources
Enter fullscreen mode Exit fullscreen mode

You should see the option to add a resource.

Conceptually:

Environment: test

--------------------------------
Resources

JavaScript
Java
Properties
XSL
...
--------------------------------
Enter fullscreen mode Exit fullscreen mode

Step 4: Add the Resource

Click:

+ Resource
Enter fullscreen mode Exit fullscreen mode

Choose the resource type.

For JavaScript:

Resource Type: JavaScript
Enter fullscreen mode Exit fullscreen mode

Upload:

generateCorrelationId.js
Enter fullscreen mode Exit fullscreen mode

Then save it.

Google's current UI instructions follow the flow of selecting the environment, opening the Resources tab, choosing + Resource, selecting the resource type, uploading the file, and adding it.

Step 5: Reference the Resource from an API Proxy

Now create a JavaScript policy.

Example:

<Javascript name="GenerateCorrelationId">
    <ResourceURL>jsc://generateCorrelationId.js</ResourceURL>
</Javascript>
Enter fullscreen mode Exit fullscreen mode

The policy doesn't contain the JavaScript itself.

Instead, it points to the resource.

Think:

JavaScript Policy
       |
       | ResourceURL
       v
generateCorrelationId.js
       |
       v
JavaScript executes
Enter fullscreen mode Exit fullscreen mode

Step 6: Deploy the API Proxy

Deploy the API proxy to the same environment where the resource exists.

For example:

Environment
    |
    ├── generateCorrelationId.js
    |
    └── Payment API
Enter fullscreen mode Exit fullscreen mode

The API proxy can now resolve the environment-level resource.

Using the Apigee API

Environment resources can also be managed programmatically.

The environment resource endpoint follows this structure:

/organizations/{organization}/environments/{environment}/resourcefiles
Enter fullscreen mode Exit fullscreen mode

For example:

curl -X POST \
"https://apigee.googleapis.com/v1/organizations/my-org/environments/test/resourcefiles?name=generateCorrelationId.js&type=jsc" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary @generateCorrelationId.js
Enter fullscreen mode Exit fullscreen mode

The important pieces are:

organization
    ↓
environment
    ↓
resourcefiles
    ↓
resource name
    ↓
resource type
Enter fullscreen mode Exit fullscreen mode

Google's API documentation confirms that environment-level resources can be created through the resourcefiles API and that the resource type and name are supplied as parameters.

Listing Environment Resources

You can also list resources in an environment.

curl -X GET \
"https://apigee.googleapis.com/v1/organizations/my-org/environments/test/resourcefiles" \
-H "Authorization: Bearer $TOKEN"
Enter fullscreen mode Exit fullscreen mode

A response can look conceptually like:

{
  "resourceFile": [
    {
      "name": "generateCorrelationId.js",
      "type": "jsc"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

You can also filter the list by resource type. The Apigee API supports listing environment resources and filtering by types such as java, jsc, properties, py, wsdl, xsd, and xsl.

Real-World Use Cases

Environment Resources are especially useful when you have reusable functionality.

1. Shared JavaScript Logic

For example:

validateRequest.js
maskSensitiveData.js
generateCorrelationId.js
commonFunctions.js
Enter fullscreen mode Exit fullscreen mode

Multiple API proxies can reuse them.

2. JavaCallout Libraries

You can store Java JAR resources at the environment level and reference them from JavaCallout policies.

For example:

common-utils.jar
Enter fullscreen mode Exit fullscreen mode

could contain reusable Java functionality.

Be careful with Java resource packaging and dependencies when using JavaCallouts.

3. XML Transformations

Suppose several APIs need the same XML transformation.

You could store:

payment-transform.xsl
Enter fullscreen mode Exit fullscreen mode

as an environment resource.

Then an XSLTransform policy can use it.

4. Shared Configuration Files

You may have configuration information that is appropriate to package as a resource file.

For example:

transformation.properties
Enter fullscreen mode Exit fullscreen mode

However, don't put secrets such as passwords, private keys, or API credentials into a normal resource file.

Use appropriate secret/configuration mechanisms such as Google Cloud Secret Manager, keystores, or KVMs, depending on the requirement.

Environment Resources vs Shared Flows

Another common interview question:

Are Environment Resources and Shared Flows the same?

No.

They solve different problems.

Environment Resource

Provides reusable:

Code
Files
Configuration artifacts
Transformation files
Libraries
Enter fullscreen mode Exit fullscreen mode

Shared Flow

Provides reusable:

API processing logic
Policies
Flow steps
Common security logic
Traffic management logic
Enter fullscreen mode Exit fullscreen mode

For example:

Shared Flow
 ├── Verify API Key
 ├── OAuth validation
 ├── Spike Arrest
 └── JavaScript Policy
          |
          └── shared.js
Enter fullscreen mode Exit fullscreen mode

Here:

  • Shared Flow = reusable flow logic
  • Environment Resource = reusable file

They can work together.

Environment Resources vs KVM vs Shared Flow

Here's a quick comparison:

Feature Main Purpose
API Proxy Resource Resource specific to a proxy revision
Environment Resource Resource shared within an environment
KVM Store key-value configuration/data
Shared Flow Reuse API processing logic
Keystore Store certificates/private keys
Truststore Store trusted certificates

A simple mental model:

                 Apigee X Environment
                         |
       +-----------------+------------------+
       |                 |                  |
       v                 v                  v
 Environment       Shared Flow           KVM
  Resources       reusable logic       key/value data
       |
       +── JS
       +── Java
       +── XSL
       +── Properties
Enter fullscreen mode Exit fullscreen mode

Important Environment Boundary

Suppose you have:

test environment
prod environment
Enter fullscreen mode Exit fullscreen mode

And:

test
 └── validateRequest.js
Enter fullscreen mode Exit fullscreen mode

That doesn't mean:

prod
 └── validateRequest.js
Enter fullscreen mode Exit fullscreen mode

automatically exists.

The resource is associated with the environment where it was created.

Therefore, if production needs the resource, you need to manage the corresponding production resource separately.

This is especially important in CI/CD pipelines.

Environment Resources and CI/CD

Imagine your deployment pipeline:

Developer
    |
    v
Git Repository
    |
    v
CI/CD Pipeline
    |
    +----------+
    |          |
    v          v
  TEST       PROD
    |          |
    v          v
Resources   Resources
Enter fullscreen mode Exit fullscreen mode

You should treat environment resources as part of your deployment/configuration lifecycle.

For example:

repository/
│
├── proxies/
│   └── payment-api/
│
├── resources/
│   ├── test/
│   │   └── validateRequest.js
│   │
│   └── prod/
│       └── validateRequest.js
│
└── pipeline/
Enter fullscreen mode Exit fullscreen mode

This allows you to manage resource changes through version control and automated deployment processes.

Common Mistakes to Avoid

Mistake 1: Putting Everything in Environment Resources

Don't make every file environment-scoped just because it can be shared.

If a resource belongs only to one API proxy, a proxy-revision resource may be more appropriate.

Mistake 2: Storing Secrets in Resource Files

Avoid storing:

password
private key
client secret
API credential
database password
Enter fullscreen mode Exit fullscreen mode

inside a JavaScript or properties resource.

Use appropriate secret-management mechanisms instead.

Mistake 3: Forgetting Environment Differences

A resource in:

test
Enter fullscreen mode Exit fullscreen mode

doesn't automatically become a resource in:

prod
Enter fullscreen mode Exit fullscreen mode

Make sure your CI/CD process handles environment-specific resources.

Mistake 4: Duplicate Resource Names

Be careful if the same resource name exists at both:

Proxy Revision
Enter fullscreen mode Exit fullscreen mode

and:

Environment
Enter fullscreen mode Exit fullscreen mode

Because Apigee resolves the more specific resource first. This can lead to unexpected behavior if developers don't realize that a proxy-level resource is overriding an environment-level resource.

Mistake 5: Using Resources When You Need Runtime Configuration

For example, don't create a JavaScript file every time a backend URL changes.

For runtime configuration, consider appropriate configuration mechanisms such as KVMs.

Best Practices for Environment Resources

1. Use Environment Resources for Genuine Reuse

Ask:

"Will multiple API proxies need this?"

If yes, an environment resource may be a good candidate.

2. Keep Resource Names Descriptive

Prefer:

generateCorrelationId.js
validatePaymentRequest.js
commonXmlTransform.xsl
Enter fullscreen mode Exit fullscreen mode

instead of:

test.js
common.js
file1.js
Enter fullscreen mode Exit fullscreen mode

Good naming makes troubleshooting much easier.

3. Version Your Resource Changes

Treat resource files like application code.

Use:

Git
CI/CD
Code Review
Testing
Enter fullscreen mode Exit fullscreen mode

rather than manually changing production resources whenever possible.

4. Separate Environment-Specific Resources

For example:

test
 └── configuration.properties

prod
 └── configuration.properties
Enter fullscreen mode Exit fullscreen mode

Make sure your deployment process knows which version belongs to which environment.

5. Monitor Resource Usage

If a shared resource is used by 20 API proxies, a change to that resource could potentially affect all 20.

Therefore:

The more widely a resource is shared, the more carefully it should be tested.

Interview Question: What Are Environment Resources in Apigee X?

Here's a concise interview-ready answer:

Environment Resources in Apigee X are reusable resource files stored at the environment level. They can be accessed by multiple API proxies deployed in that environment. Resources can include JavaScript, Java JARs, XSL, XSD, WSDL, Python, and properties files. They help avoid duplicating common code or configuration across multiple API proxies. Apigee resolves resources from the most specific scope first, so a proxy-revision resource takes precedence over an environment-level resource with the same name.

That's a strong answer for an Apigee interview.

Interview Follow-Up: Where Would You Use Them?

A good answer would be:

"I would use Environment Resources when multiple API proxies within the same environment need the same reusable file, such as common JavaScript logic, XSL transformations, or JavaCallout libraries. If the resource is specific to one proxy, I would keep it at the proxy-revision level instead."

Interview Follow-Up: Are Environment Resources Available Across Environments?

No.

If you have:

test
 └── common.js
Enter fullscreen mode Exit fullscreen mode

that doesn't automatically mean:

prod
 └── common.js
Enter fullscreen mode Exit fullscreen mode

exists.

Environment-level resources belong to their respective environment.

Interview Follow-Up: What Happens If the Same Resource Exists at Both Levels?

Suppose:

Proxy Revision
 └── common.js

Environment
 └── common.js
Enter fullscreen mode Exit fullscreen mode

The proxy-revision resource is more specific.

Therefore:

Proxy Revision
      ↓
Environment
Enter fullscreen mode Exit fullscreen mode

Apigee checks the proxy revision first and then the environment.

Environment Resources: The Big Picture

Let's put everything together.

                         Apigee X
                            |
                     Organization
                            |
             +--------------+--------------+
             |                             |
          TEST                           PROD
        Environment                    Environment
             |                             |
      +------+-------+               +-----+------+
      |              |               |            |
      v              v               v            v
   Proxy A        Proxy B          Proxy C      Proxy D
      |              |               |            |
      +-------+------+               +-----+------+
              |                            |
              v                            v
       Environment Resources        Environment Resources
              |                            |
        +-----+------+               +-----+------+
        |            |               |            |
       JS           XSL             JS           Java
Enter fullscreen mode Exit fullscreen mode

The key relationship is:

Environment
     |
     +── Environment Resource
     |
     +── API Proxy
     |
     +── Shared Flow
     |
     +── Other environment-level configuration
Enter fullscreen mode Exit fullscreen mode

Environment Resources vs API Proxy Resources: Final Comparison

Feature Proxy Revision Resource Environment Resource
Scope API proxy revision Environment
Reusable by multiple proxies? No Yes
Useful for shared code? Limited Yes
Example Proxy-specific JS Common JS
Deployment dependency Proxy revision Environment
Priority during resolution Higher Lower
Best use Proxy-specific functionality Common environment-level functionality

The easiest way to remember it:

Proxy Resource = Private

Environment Resource = Shared within the environment

Conclusion

Environment Resources are a simple but powerful feature of Apigee X API management.

Instead of duplicating the same JavaScript, Java, XSL, or other resource files across multiple API proxies, you can store reusable resources at the environment level.

The most important concepts to remember are:

  1. Environment Resources are resource files stored at the environment level.
  2. Multiple API proxies in that environment can use them.
  3. They are different from KVMs and Shared Flows.
  4. They can contain resources such as JavaScript, Java, XSL, XSD, WSDL, and properties files.
  5. Proxy-revision resources are more specific than environment resources.
  6. Resources don't automatically move between environments.
  7. Environment Resources are excellent for reusable functionality, but shouldn't be used as a replacement for secret management or runtime configuration mechanisms.

Once you understand Environment Resources, concepts such as Shared Flows, KVMs, JavaScript policies, JavaCallouts, CI/CD, and Apigee environment management become much easier to connect.

So the next time you see:

<ResourceURL>jsc://common.js</ResourceURL>
Enter fullscreen mode Exit fullscreen mode

don't just think:

"Apigee is executing a JavaScript file."

Think:

"Apigee is resolving a reusable resource from the appropriate scope."

That's the real concept behind Environment Resources.

🚀 Try It Yourself

Create a small JavaScript resource such as:

context.setVariable(
    "custom.message",
    "Hello from Environment Resource"
);
Enter fullscreen mode Exit fullscreen mode

Store it at the environment level and reference it from a JavaScript policy.

Then deploy two different API proxies in the same environment and make both use the same resource.

You'll immediately see why environment-level resources are useful for building maintainable API platforms.

Official References


💬 Your Turn

Have you used Environment Resources in Apigee X in a real project?

What did you use them for — JavaScript, JavaCallout, XSL transformation, or something else?

Share your experience or questions in the comments.

If you found this guide useful, follow for more practical Apigee X, API management, Java, Spring Boot, and cloud-native engineering content.

Top comments (0)