Skip to content

Commit

Permalink
Updated virtual endpoint and JS docs
Browse files Browse the repository at this point in the history
  • Loading branch information
andyo-tyk committed Mar 1, 2024
1 parent 2da30e0 commit 4f60755
Show file tree
Hide file tree
Showing 16 changed files with 692 additions and 422 deletions.
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.
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,27 +1,128 @@
---
date: 2017-03-23T18:08:16Z
title: Virtual Endpoint Demonstration
menu:
main:
parent: "Compose APIs"
weight: 2
title: Virtual Endpoint examples
description: "Examples of Virtual Endpoints"
tags: ["JavaScript", "JS", "middleware", "scripting", "JSVM", "examples", "virtual endpoint"]
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
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).

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`.
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):
```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 matters
log("auth Header: " + request.Headers["Authorization"]) // case matters

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")
```

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

Every line in the script gives an example of a functionality usage:
3. The virtual endpoint will terminate the request and return this response:
```
HTTP/1.1 200 OK
Date: Thu, 29 Feb 2024 17:39:00 GMT
Server: tyk
X-Ratelimit-Limit: 0
X-Ratelimit-Remaining: 0
X-Ratelimit-Reset: 0
X-Test: virtual-header
X-Test-2: virtual-header-2
Content-Length: 27
Content-Type: text/plain; charset=utf-8
VIRTUAL ENDPOINT EXAMPLE #1
```

* 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`.
4. The gateway logs will include:
```
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
```

## 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):
```.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/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
X-Ratelimit-Limit: 0
X-Ratelimit-Remaining: 0
X-Ratelimit-Reset: 0
Content-Length: 26
Content-Type: text/plain; charset=utf-8
VIRTUAL ENDPOINT EXAMPLE #2
```

## Example 3: Advanced example
In this example, every line in the script gives an example of a functionality usage, including:
- 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`.

Paste the following code in the **Code editor**.

```{.json}
function myVirtualHandlerGetHeaders (request, session, config) {
Expand Down Expand Up @@ -58,7 +159,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,18 +173,11 @@ 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 >}}


The virtual function is `base64` encoded in the `function_source_uri` field.
#### Running the Advanced example
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

Run the following command:
Create a new Tyk Classic API using that API definition and then run the following command to send a request to the API endpoint where the :
`curl http://tyk-gateway:8080/testvirtualendpoint2/headers -H "location: /get" -v`

This should return the following:
Expand Down Expand Up @@ -114,7 +208,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:

```
[Jun 13 14:45:21] DEBUG jsvm: Running: myVirtualHandlerGetHeaders
Expand All @@ -138,3 +233,59 @@ 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

0 comments on commit 4f60755

Please sign in to comment.