Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DX-1142, TT-11620] Updated virtual endpoint and JS docs #4186

Merged
merged 38 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b9dc57d
Updated virtual endpoint and JS docs
andyo-tyk Mar 1, 2024
4d8907c
Adjusted for new contract
andyo-tyk Mar 4, 2024
d3a8a9a
Added detail on the JSVM
andyo-tyk Mar 4, 2024
bfe1edd
Update tyk-docs/content/advanced-configuration/compose-apis/demo-virt…
dcs3spp Mar 19, 2024
db33c41
Update tyk-docs/content/advanced-configuration/compose-apis/demo-virt…
dcs3spp Mar 19, 2024
46bea3a
Update tyk-docs/content/advanced-configuration/compose-apis/demo-virt…
dcs3spp Mar 19, 2024
dc7ca59
Update tyk-docs/content/plugins/supported-languages/javascript-middle…
dcs3spp Mar 19, 2024
6d1092a
Update tyk-docs/content/plugins/supported-languages/javascript-middle…
dcs3spp Mar 19, 2024
7d5ce10
Update tyk-docs/content/advanced-configuration/compose-apis/virtual-e…
dcs3spp Mar 19, 2024
bf3e8b0
Update tyk-docs/content/advanced-configuration/compose-apis/demo-virt…
dcs3spp Mar 19, 2024
6513c90
Update tyk-docs/content/product-stack/tyk-gateway/middleware/virtual-…
dcs3spp Mar 19, 2024
dce7e9f
Update tyk-docs/content/product-stack/tyk-gateway/middleware/virtual-…
dcs3spp Mar 19, 2024
c213638
Update tyk-docs/content/product-stack/tyk-gateway/middleware/virtual-…
dcs3spp Mar 19, 2024
4383ab2
Update tyk-docs/content/product-stack/tyk-gateway/middleware/virtual-…
dcs3spp Mar 19, 2024
8e0699b
Update tyk-docs/content/product-stack/tyk-gateway/middleware/virtual-…
dcs3spp Mar 19, 2024
e222e2c
Update tyk-docs/content/plugins/supported-languages/javascript-middle…
dcs3spp Mar 19, 2024
ff55358
Update tyk-docs/content/plugins/supported-languages/javascript-middle…
dcs3spp Mar 19, 2024
3c4a8d0
Update tyk-docs/content/plugins/supported-languages/javascript-middle…
dcs3spp Mar 19, 2024
1746db2
Update tyk-docs/content/plugins/supported-languages/javascript-middle…
dcs3spp Mar 19, 2024
36c910c
Update tyk-docs/content/plugins/supported-languages/javascript-middle…
dcs3spp Mar 19, 2024
57bc128
fix CI check caused by unpublished page in menu.yaml
Mar 21, 2024
eb163ac
Sanitize virtual endpoints docs in product-stack
Mar 22, 2024
d4159ae
Get rid of x-ratelimit headers in examples, proof function in tyk cla…
Mar 22, 2024
ae8994e
Fix indentation on tyk-oas javascript example
Mar 22, 2024
8e6e01d
Add before list spacing
Mar 22, 2024
b5f3fe1
Update advanced-configuration, compose apis
Mar 22, 2024
d432fe3
Fix indenting on code snippets for javascript-api.md
Mar 22, 2024
da063cc
Fix note layout, missed newline - reindent TykJSHttpResponse
Mar 22, 2024
877c470
Remove x-ratelimit headers from examples, not essential/valuable
Mar 22, 2024
db12583
More code block highlighting fixes
Mar 22, 2024
dfafc30
Fix code block highlight for javascript apis
Mar 22, 2024
66af1a7
Sanitize all code blocks on modified files
Mar 22, 2024
cbd1049
Update use of console.log to log
Mar 22, 2024
20d5708
Remove tyk-docs/content/advanced-configuration/compose-apis.md
Mar 28, 2024
66bd1e5
Merge branch 'master' into Improved-virtual-endpoint-and-javascript
andyo-tyk Mar 30, 2024
71a9204
Added screenshots, responses to review feedback
andyo-tyk Mar 31, 2024
7215d3a
Merge branch 'master' into Improved-virtual-endpoint-and-javascript
dcs3spp Apr 3, 2024
80a5edb
Merge branch 'master' into Improved-virtual-endpoint-and-javascript
dcs3spp Apr 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andyo-tyk can you update this screenshot with the corrected API definition? The code snippet had a double-space, which was modified in the markdown ; I've chosen to update the example apidef to match the code block.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,29 +1,140 @@
---
date: 2017-03-23T18:08:16Z
title: Virtual Endpoint Demonstration
menu:
main:
parent: "Compose APIs"
weight: 2
title: Virtual Endpoint examples
tags:
- JavaScript
- JS
- middleware
- scripting
- JSVM
- examples
- virtual endpoint
description: Examples of Virtual Endpoints
date: "2017-03-23T18:08:16Z"
aliases:
- /advanced-configuration/compose-apis/sample-batch-funtion/
---

## Set up the Virtual Endpoint
Here we offer some examples to demonstrate valid use of JavaScript within Virtual Endpoints. You can either copy and paste the JavaScript code into the code editor in the Tyk Dashboard API Designer, or create a file and place it in a subdirectory of the Tyk configuration environment (for example under the `middleware` folder in your Tyk installation).

Virtual Endpoints are defined per API on an endpoint level. To set up a Virtual Endpoint:
## Example 1: Accessing Tyk data objects

1. From the **Endpoint Designer**, Add a new Endpoint.
2. From the Plugins drop-down list, select **Virtual Endpoint**.
3. From the Virtual Endpoint settings, add a unique name in the **JS function to call** option. You should also use the same name inside the function code. For this demo, we will use `myVirtualHandlerGetHeaders`.
In this example, we demonstrate how you can access different [external Tyk objects]({{< ref "plugins/supported-languages/javascript-middleware/middleware-scripting-guide#accessing-external-and-dynamic-data" >}}) (API request, session key, API definition).

Every line in the script gives an example of a functionality usage:
1. Enable the Virtual Endpoint middleware on an endpoint of your API and paste this JavaScript into the API Designer (or save in a file and reference it from the middleware config):
andyo-tyk marked this conversation as resolved.
Show resolved Hide resolved

* How to get form param
* How to get specific key inside json variable
* The structure of request object with `Body`, `Headers`, (need to add session object examples)Using `TykMakeHttpRequest`, and the json it returns - `.Code` and `.Body`.
```javascript
function myFirstVirtualHandler (request, session, config) {
log("Virtual Test running")

log("Request Body: " + request.Body)
log("Session: " + JSON.stringify(session.allowance))
log("Config: " + JSON.stringify(config.APIID))
log("param-1: " + request.Params["param1"]) // case sensitive
log("auth Header: " + request.Headers["Authorization"]) // case sensitive

var responseObject = {
Body: "VIRTUAL ENDPOINT EXAMPLE #1",
Headers: {
"x-test": "virtual-header",
"x-test-2": "virtual-header-2"
},
Code: 200
}

return TykJsResponse(responseObject, session.meta_data)
}
log("Virtual Test initialised")
titpetric marked this conversation as resolved.
Show resolved Hide resolved
```

2. Make a call to your API endpoint passing a request body, a value in the `Authorization` header and a query parameter `param1`.

3. The virtual endpoint will terminate the request and return this response:

```http
HTTP/1.1 200 OK
Date: Thu, 29 Feb 2024 17:39:00 GMT
Server: tyk
X-Test: virtual-header
X-Test-2: virtual-header-2
Content-Length: 27
Content-Type: text/plain; charset=utf-8

VIRTUAL ENDPOINT EXAMPLE #1
```

4. The gateway logs will include:

```text
time="" level=info msg="Virtual Test running" prefix=jsvm type=log-msg
time="" level=info msg="Request Body: <your-request-body>" prefix=jsvm type=log-msg
time="" level=info msg="Session: <allowance-from-your-session-key>" prefix=jsvm type=log-msg
time="" level=info msg="Config: <your-APIID>" prefix=jsvm type=log-msg
time="" level=info msg="param-1: <your_query_parameter>" prefix=jsvm type=log-msg
time="" level=info msg="auth Header: <your-auth-header>" prefix=jsvm type=log-msg
```
dcs3spp marked this conversation as resolved.
Show resolved Hide resolved

## Example 2: Accessing custom attributes in the API Definition

You can add [custom attributes]({{< ref "plugins/supported-languages/javascript-middleware/middleware-scripting-guide#passing-custom-attributes-to-middleware" >}}) to the API definition and access these from within your Virtual Endpoint.

1. Add the following custom attributes to your API definition:

```json
{
"string": "string",
"map": {
" key": 3
},
"num": 4
}
```

2. Enable the Virtual Endpoint middleware on an endpoint of your API and paste this JavaScript into the API Designer (or save in a file and reference it from the middleware config):
dcs3spp marked this conversation as resolved.
Show resolved Hide resolved

```js
function mySecondVirtualHandler (request, session, config) {
var responseObject = {
Body: "VIRTUAL ENDPOINT EXAMPLE #2",
Headers: {
"foo-header": "bar",
"map-header": JSON.stringify(config.config_data.map),
"string-header": config.config_data.string,
"num-header": JSON.stringify(config.config_data.num)
},
Code: 200
}
return TykJsResponse(responseObject, session.meta_data)
}
```

3. Make a call to your API endpoint.

4. The virtual endpoint will terminate the request and return this response:

```http
HTTP/1.1 200 OK
Date: Thu, 29 Feb 2024 17:29:12 GMT
Foo-Header: bar
Map-Header: {" key":3}
Num-Header: 4
Server: tyk
String-Header: string
Content-Length: 26
Content-Type: text/plain; charset=utf-8

VIRTUAL ENDPOINT EXAMPLE #2
```

## Example 3: Advanced example

Paste the following code in the **Code editor**.
In this example, every line in the script gives an example of a functionality usage, including:

```{.json}
- how to get form param
- how to get to a specific key inside a JSON variable
- the structure of the request object
- using `TykMakeHttpRequest` to make an HTTP request from within the virtual endpoint, and the json it returns - `.Code` and `.Body`.

```js
function myVirtualHandlerGetHeaders (request, session, config) {
rawlog("Virtual Test running")

Expand Down Expand Up @@ -58,7 +169,7 @@ function myVirtualHandlerGetHeaders (request, session, config) {
var bodyObject = JSON.parse(usableResponse.Body);

var responseObject = {
//Body: "THIS IS A VIRTUAL RESPONSE",
//Body: "THIS IS A VIRTUAL RESPONSE",
Body: "yo yo",
Headers: {
"test": "virtual",
Expand All @@ -72,23 +183,20 @@ function myVirtualHandlerGetHeaders (request, session, config) {
return TykJsResponse(responseObject, session.meta_data)
}
```
{{< note success >}}
**Note**

Another option, instead of the steps above, you can use this Gist to import the API definition - [API Definition Import](https://gist.github.com/letzya/5b5edb3f9f59ab8e0c3c614219c40747)
{{< /note >}}

#### Running the Advanced example

The virtual function is `base64` encoded in the `function_source_uri` field.
You can find a Tyk Classic API definition [here](https://gist.github.com/letzya/5b5edb3f9f59ab8e0c3c614219c40747) that includes the advanced example, with the JS encoded `inline` within the middleware config for the `GET /headers` endpoint.

## Demonstrating the Virtual Endpoint
Create a new Tyk Classic API using that API definition and then run the following command to send a request to the API endpoint:

Run the following command:
`curl http://tyk-gateway:8080/testvirtualendpoint2/headers -H "location: /get" -v`
```bash
curl http://tyk-gateway:8080/testvirtualendpoint2/headers -H "location: /get" -v
```

This should return the following:

```
```http
Trying 127.0.0.1...
TCP_NODELAY set
Connected to tyk-gateway (127.0.0.1) port 8080 (#0)
Expand All @@ -104,19 +212,18 @@ Date: Fri, 08 Jun 2018 21:53:57 GMT
Server: tyk
Test: virtual
Test-2: virtual
X-Ratelimit-Limit: 0
X-Ratelimit-Remaining: 0
X-Ratelimit-Reset: 0
Content-Length: 5
Content-Type: text/plain; charset=utf-8

Connection #0 to host tyk-gateway left intact
yo yo
```

## Checking the Tyk Gateway Logs
#### Checking the Tyk Gateway Logs

```
The `log` and `rawlog` commands in the JS function write to the Tyk Gateway logs. If you check the logs you should see the following:

```text
[Jun 13 14:45:21] DEBUG jsvm: Running: myVirtualHandlerGetHeaders
Virtual Test running
[Jun 13 14:45:21] INFO jsvm-logmsg: Request Session: {"access_rights":null,"alias":"","allowance":0,"apply_policies":null,"apply_policy_id":"","basic_auth_data":{"hash_type":"","password":""},"certificate":"","data_expires":0,"enable_detail_recording":false,"expires":0,"hmac_enabled":false,"hmac_string":"","id_extractor_deadline":0,"is_inactive":false,"jwt_data":{"secret":""},"last_check":0,"last_updated":"","meta_data":null,"monitor":{"trigger_limits":null},"oauth_client_id":"","oauth_keys":null,"org_id":"","per":0,"quota_max":0,"quota_remaining":0,"quota_renewal_rate":0,"quota_renews":0,"rate":0,"session_lifetime":0,"tags":null} type=log-msg
Expand All @@ -138,3 +245,60 @@ Virtual Test ended
[Jun 13 14:45:22] DEBUG JSVM Virtual Endpoint execution took: (ns) 191031553
```

## Example 4: Aggregating upstream calls using batch processing

One of the most common use cases for virtual endpoints is to provide some form of aggregate data to your users, combining the responses from multiple upstream service calls. This virtual endpoint function will do just that using the batch processing function from the [JavaScript API]({{< ref "plugins/supported-languages/javascript-middleware/javascript-api" >}})

```js
function batchTest(request, session, config) {
// Set up a response object
var response = {
Body: "",
Headers: {
"test": "virtual-header-1",
"test-2": "virtual-header-2",
"content-type": "application/json"
},
Code: 200
}

// Batch request
var batch = {
"requests": [
{
"method": "GET",
"headers": {
"x-tyk-test": "1",
"x-tyk-version": "1.2",
"authorization": "1dbc83b9c431649d7698faa9797e2900f"
},
"body": "",
"relative_url": "http://httpbin.org/get"
},
{
"method": "GET",
"headers": {},
"body": "",
"relative_url": "http://httpbin.org/user-agent"
}
],
"suppress_parallel_execution": false
}

log("[Virtual Test] Making Upstream Batch Request")
var newBody = TykBatchRequest(JSON.stringify(batch))

// We know that the requests return JSON in their body, lets flatten it
var asJS = JSON.parse(newBody)
for (var i in asJS) {
asJS[i].body = JSON.parse(asJS[i].body)
}

// We need to send a string object back to Tyk to embed in the response
response.Body = JSON.stringify(asJS)

return TykJsResponse(response, session.meta_data)

}
log("Batch Test initialised")
```

This file was deleted.

Loading
Loading