Building an Express Gateway Policy
Tags: express, gateway, api, microservices
Published: 2021-08-29 08:36:21

This post will show you how to build a policy (middleware) for your [express gateway](https://github.com/ExpressGateway/express-gateway). Before creating a policy, we need to create a plugin.

## Creating a plugin
To create a plugin, we need to add a folder `plugins/my-plugin` for it and a manifest file `plugins/my-plugin/manifest.js` with the following content
```js
// plugins/my-plugin/manifest.js
module.exports = {
  version: '0.0.1',
  schema: {
    "$id": "https://express-gateway.io/schemas/plugins/my-plugin.json"
  }
}
```

Once this is done, we need to register the plugin in the `system.config.yml` file. Depending on your file structure, the file path may contain more or less `../` than this example.
```diff
# system.config.yml

plugins:
+  my-plugin:
+    package: '../../../plugins/my-plugin/manifest.js'
```

## Creating the policy
Now that we have a plugin, we can start creating our policy. Add a policies folder `plugins/my-plugin/policies` and the policy itself `plugins/my-plugin/policies/my-policy.js` with the following content
```js
// plugins/my-plugin/policies/my-policy.js
module.exports = {
  name: 'my-policy',
  schema: {
    $id: 'http://express-gateway.io/schemas/policies/my-policy.json',
    type: 'object'
  },
  policy: (actionParams) => {
    return (req, res, next) => {
      // TODO: Implement me
      console.log('hello world');
      next();
    };
  }
};
```

The `policy` function will be the place where you implement your specific use case.

Now we need to register the policy as part of the plugin
```diff
// plugins/my-plugin/manifest.js
module.exports = {
  version: '0.0.1',
+ init: function (pluginContext) {
+   let policy = require('./policies/my-policy')
+   pluginContext.registerPolicy(policy)
+ },
+ policies: ['my-policy'],
  schema: {
    "$id": "https://express-gateway.io/schemas/plugins/my-plugin.json"
  }
}
```

## Using the policy
Finally, we can add the policy as any other default policy in the `gateway.config.yml`
```diff
# gateway.config.yml

policies:
  - log
  - jwt
+ - my-plugin
```
and use it in our pipelines
```diff
# gateway.config.yml

pipelines:
  my-pipeline:
    policies:
+     - my-plugin:
      - log:
        - action:
            message: ${req.method} ${req.originalUrl}
```

Now we are finished with our policy, but we can still enhance it a bit. 

## Adding parameters
In the case, that you want to configure your policy (without changing the code) you can specify parameters. The syntax used is called [Json Schema](https://json-schema.org/understanding-json-schema/reference/index.html). You can have a look at their documentation for the type that you need. In this case, we add one parameter `myarray` with the type `string[]`
```diff
// plugins/my-plugin/policies/my-policy.js

  schema: {
    $id: 'http://express-gateway.io/schemas/policies/my-policy.json',
-   type: 'object'
+   type: 'object',
+   properties: {
+     myarray: {
+       "type": "array",
+       "items": {
+         "type": "string"
+       }
+     }
+   }
  },
```

After that, we can pass our value from the pipeline
```diff
# gateway.config.yml

    policies:
     - my-plugin:
+       - action:
+           myarray: ['value1', 'value2']
```

and use it within the `policy` function: `actionParams.myarray`.

---

I hope this helped you understand how to set up a policy in an express gateway pipeline.

## Sources/Further Reading
- https://www.express-gateway.io/docs/plugins/policy-development/
- https://www.express-gateway.io/docs/plugins/plugin-development/
- https://stackoverflow.com/a/62183683