Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
paulr34 committed Nov 12, 2024
1 parent b9a1e4c commit 390df00
Showing 1 changed file with 31 additions and 56 deletions.
87 changes: 31 additions & 56 deletions docs/external-helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,23 @@ This guide explains how to add and manage externalized helper functions in the S

This design enables SDK developers to specify helper functions via the `gen-template.json` configuration file, which ZAP consumes during binary creation. The SDK can then call these helpers, passing in the necessary data, making them more flexible and reducing dependency on the internal ZAP codebase.

## Background
### How External Helpers Work

### Previous Approach
With external helpers, the SDK can call functions that are defined outside of the ZAP repository. Here's how it works:

In the earlier design, SDK helpers were external to ZAP. However, to function correctly, these helpers required access to ZAP’s source code, especially certain files within the ZAP repository. This created challenges:

- When ZAP function names changed, corresponding updates had to be made across the SDK.
- SDK developers were constrained by these internal dependencies, requiring explicit imports or "requires" of ZAP files.

### New Design Pattern

The new design pattern aims to free SDK developers from being tied to the internal structure of the ZAP repository, while still allowing the SDK to interact with ZAP's API. The new design works as follows:

1. **Externalized Helpers**: SDK developers can create their own helper functions and specify the relative path to these helpers in the `gen-template.json` configuration file.
2. **Data Flow**: ZAP will transmit the necessary API object to these helpers at runtime during binary creation, allowing them to work with ZAP data without needing to directly interact with ZAP’s source code.
3. **API Abstraction**: The API object passed to the helpers contains abstracted ZAP method definitions, meaning SDK developers do not need to worry about changes in query or method names within ZAP. If a query or method name changes, only the ZAP team needs to make updates to the API; the SDK code remains unaffected.

### Example

In the provided code snippet, the SDK receives an API object containing "attributes" which invokes a query. In the event of a query name change, the ZAP developer updates the API, relieving the SDK developer from making any adjustments:

```javascript
/**
* Returns an array of attributes for a given cluster.
* The cluster input is required to come from a script-api in this module.
*
* @param {*} context
* @param {*} endpoint
* @param {*} cluster
*/
function attributes(context, endpoint, cluster) {
return queryEndpoint.selectEndpointClusterAttributes(
context.db,
cluster.clusterId,
cluster.side,
endpoint.endpointTypeRef
)
}
```

In this example, the attributes function makes use of the queryEndpoint.selectEndpointClusterAttributes method. If ZAP changes the method or its name, the SDK developers are not required to update their code. ZAP abstracts these changes through the API object passed to the helper, which remains stable.
1. **Externalized Helpers**: SDK developers create their own helper functions and specify the relative path to these functions in the gen-template.json configuration file.
2. **Data Flow**: ZAP will pass the required API object to these helpers at runtime, allowing them to interact with the ZAP data without needing direct access to the ZAP source code.
3. **API Abstraction**: The API object passed to the helper functions abstracts ZAP method definitions. SDK developers don’t need to worry about changes to method names or queries within ZAP, as any such changes will be handled by ZAP itself, without affecting the SDK code.

## How to Add Externalized Helpers

The process for adding externalized helpers follows a new design pattern that enables SDK developers to extend functionality without modifying the ZAP repository.
Here’s the step-by-step process to add your own external helper file to the SDK:

### Step 1: Define Helper Functions

Your externalized helper functions should be asynchronous and accept the necessary data passed from ZAP, typically in the form of an api object. Here's an example of a helper that retrieves and counts available events:
External helper functions should be asynchronous and accept the necessary data passed from ZAP, typically via the api object. These helpers can perform any logic, such as querying ZAP's data or processing it.

Here’s an example of a helper that retrieves and counts available clusters:

```javascript
/**
Expand All @@ -69,13 +37,19 @@ async function get_total_events_helper(api) {
}
```

Each helper function can interact with the API object provided by ZAP to fetch and process data as needed.
### In this example:

- The helper accepts the `api` object.
- It calls `api.availableClusters(this)` to fetch the list of available clusters.
- It then returns the total number of clusters by calculating the length of the returned array.

Each helper can interact with the ZAP API to fetch data and process it as needed, based on the context passed in.

### Step 2: Specify Helpers in gen-template.json

The gen-template.json file allows SDK developers to specify the path to the externalized helpers they wish to use. The file should include the helper file's relative path within your project structure.
The next step is to tell ZAP where to find your external helper functions. This is done by specifying the relative path to each helper file in the gen-template.json configuration file.

For example, your gen-template.json might include:
For example, your gen-template.json might look like this:

```javascript
{
Expand All @@ -86,13 +60,13 @@ For example, your gen-template.json might include:
}
```

This tells ZAP where to find your helper files during runtime.
The paths should be relative to the location of the gen-template.json file itself. This tells ZAP where to find your helper files when generating the binary.

### Step 3: Register Helpers with ZAP

In the SDK, you need to create a function to register the helpers with ZAP. ZAP will use this function to register each helper specified in gen-template.json and make them available during binary creation.
After defining and specifying your helper files, the next step is to register them with ZAP so that they can be used during binary creation. You’ll need to call helperRegister.registerHelpers() for each helper function.

Here’s an example of how to register the helpers:
Here’s an example of how to register your helpers:

```javascript
function initialize_helpers(helperRegister, context) {
Expand All @@ -112,20 +86,21 @@ function initialize_helpers(helperRegister, context) {
}
```

The helperRegister.registerHelpers function is called for each helper function you’ve defined. The context object is passed along to each helper function when invoked.
- The `helperRegister.registerHelpers()` function registers each helper.
- The first argument is the **name** of the helper.
- The second argument is the **helper function** you defined.
- The third argument is the **context object**, which contains the necessary environment or data (such as a database connection) that may be passed to the helper.

### Step 4: Use the Helpers in Your SDK Code

Once your helpers are registered, they can be called in your SDK code as needed. Here’s how the helpers can be used in templates or other components:
Once your helpers are registered, they can be used in templates or other components of the SDK as needed.

<p>Events Count: {{ get_total_events_helper(api) }}</p>
<p>Attributes Count: {{ get_total_attributes_helper(api) }}</p>
The api object, provided by ZAP, contains the data and methods required for these helpers to work.
For example, in your SDK code, you can call the helpers like this:

### Step 5: Handling Changes in ZAP

With this new design, you no longer need to worry about changes in the ZAP codebase affecting your SDK helpers. If a method or query name changes in ZAP, the ZAP team will update the API object, and the changes will be abstracted to the SDK. Your helpers remain unaffected and continue to operate as expected without requiring code changes on your part.
<p>Events Count: {{ get_total_events_helper }}</p>
<p>Attributes Count: {{ get_total_attributes_helper }}</p>
The api object, provided by ZAP, contains the data and methods required for these helpers to work.

## Conclusion

This new design pattern allows SDK developers to create externalized helpers. By leveraging the gen-template.json configuration file and the API object, SDK developers can interact with ZAP without needing direct access to ZAP’s internal source code. The approach abstracts method and query name changes in ZAP, ensuring that SDK code remains resilient to changes in the ZAP API.
This design pattern allows SDK developers to create externalized helpers. By leveraging the gen-template.json configuration file and the API object, SDK developers can interact with ZAP without needing direct access to ZAP’s internal source code. The approach abstracts method and query name changes in ZAP, ensuring that SDK code remains resilient to changes in the ZAP API.

0 comments on commit 390df00

Please sign in to comment.