Custom /hello response in Tyk

I’m trying to check the Health of the Gateway. I am seeing the default health liveliness response from tyk. Is there a way to edit/customize the health response from tyk?

If not, how can it be disabled?

Thank you.

Hi @Radhika_Bhatt,

Welcome to the community :partying_face:

Yes, you can customize the health endpoint on the Gateway config. See here.

Thank you @Ubong,

The link/doc mentions ways to customize/change the path at which we see the health endpoint results. I would like to make changes to the actual response - like remove some details that I would like to hide. For example remove Tyk version from the response. How can I do that?

Hi @Radhika_Bhatt,

I see… it’s not possible to modify the response itself… and it cannot be disabled.

You could move the control API to another port though. This would mean you would need to make CRUD requests for APIs, Policies, keys etc (including the health check) using that port, while the actual consumption of APIs will continue to be through the listen port.

To a large extent though, using a Mock Response in an API would suffice to replace calling /hello, as the API will only respond with what you’ve defined in the mock if the Gateway is up and healthy - so it’s still a health check of some sort. And you can customize the mock response as you like.

Or, If you would still prefer to use some of the details from the native /hello endpoint, you could use an API that implements Virtual Endpoint, which calls the native /hello, and does some modification to the body before returning the response.
For instance, the function below will remove the Tyk Version from the response:

function callHello(request, session, config) {
  
  //Make api call to upstream target
  newRequest = {
    "Method": "GET",
    "Domain": "http://localhost:8080",
    "Resource": "/hello"
  };

  response = TykMakeHttpRequest(JSON.stringify(newRequest));

  usableResponse = JSON.parse(response);
  var bodyObject = usableResponse.Body;

  newStr = bodyObject.substring(16,34)
  bodyObject = bodyObject.replace(newStr, '')

  var responseObject = { 
    Body: bodyObject, 
    Code: usableResponse.Code, 
    Headers: {
        "Content-Type": "application/json"
    }
  }
  return TykJsResponse(responseObject, session.meta_data)
}

This might be a little over the top, but I guess where there’s a will, there’s a way.

Hope this helps.

Thank you @Ubong for the detailed answer. Appreciated all the reference links!

I tried the mock response approach but unfortunately that still returns the former response. This is config I am using:

{
    "name": "Hello-API",
    "api_id": "hello-api",
    "org_id": "default",
    "use_keyless": true,
    "enable_context_vars": true,
    "definition": {
        "location": "header",
        "key": "version"
    },
    "auth": {
        "auth_header_name": "authorization"
    },
    "version_data": {
        "not_versioned": true,
        "default_version": "",
        "versions": {
            "Default": {
                "name": "Default",
                "expires": "",
                "paths": {
                    "ignored": [],
                    "white_list": [],
                    "black_list": []
                },
                "use_extended_paths": true,
                "global_headers": {},
                "global_headers_remove": [],
                "global_response_headers": {},
                "global_response_headers_remove": [],
                "ignore_endpoint_case": false,
                "global_size_limit": 0,
                "override_target": "",
                "extended_paths": {
                    "white_list": [
                        {
                            "path": "/hello",
                            "ignore_case": false,
                            "method_actions": {
                                "GET": {
                                    "action": "reply",
                                    "code": 200,
                                    "data": "Hello Tiki",
                                    "headers": {}
                                }
                            }
                        }
                    ]
                }
            }
        }
    },
    "enable_batch_request_support": true,
    "response_processors": [
        {
            "name": "header_injector",
            "options": {
                "add_headers": {
                    "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
                }
            }
        }
    ],
    "event_handlers": {},
    "tag_headers": [
        "Trace-Id",
        "Incoming-Trace-Id"
    ],
    "enable_coprocess_auth": true,
    "custom_middleware": {
        "pre": [
            {
                "name": "test"
            }
        ],
        "driver": "grpc"
    }
}

Hi @Radhika_Bhatt,

I don’t see a listen_path anywhere. This should be in the proxy section. Please see API def object

Then you will call hello through this API listen path, not directly on the gateway.

This
curl localhost:8080/<api-listen-path>/hello

Not this
curl localhost:8080/hello

Thanks for all the help @Ubong - I had to use a combination of the control_port and mock response for it to work. Without changing the control_port the hello response would always be overridden by the default response.

While my key objective has been achieved, I do have a couple of follow-up questions. This is the config I am using:

{
    "name": "Hello-API",
    "api_id": "hello-api",
    "org_id": "default",
    "use_keyless": true,
    "enable_context_vars": true,
    "definition": {
        "location": "header",
        "key": "version"
    },
    "auth": {
        "auth_header_name": ""
    },
    "version_data": {
        "not_versioned": true,
        "default_version": "",
        "versions": {
            "Default": {
                "name": "Default",
                "expires": "",
                "paths": {
                    "ignored": [],
                    "white_list": [],
                    "black_list": []
                },
                "use_extended_paths": true,
                "global_headers": {},
                "global_headers_remove": [],
                "global_response_headers": {},
                "global_response_headers_remove": [],
                "ignore_endpoint_case": false,
                "global_size_limit": 0,
                "extended_paths": {
                    "white_list": [],
                    "ignored": [
                        {
                            "path": "/hello$",
                            "ignore_case": false,
                            "method_actions": {
                                "GET": {
                                    "action": "reply",
                                    "code": 200,
                                    "headers": {
                                        "x-tyk-override": "tyk-override"
                                    }
                                }
                            }
                        }
                    ],
                    "black_list": [],
                    "url_rewrites": [
                        {
                            "path": "/",
                            "method": "GET",
                            "match_pattern": "/",
                            "rewrite_to": "/",
                            "triggers": []
                        }
                    ]
                }
            }
        }
    },
    "proxy": {
        "listen_path": "/{Path:hello$}",
        "strip_listen_path": false,
        "ignore_case": false
    },
    "enable_batch_request_support": true,
    "response_processors": [
        {
            "name": "header_injector",
            "options": {
                "add_headers": {
                    "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
                }
            }
        }
    ],
    "event_handlers": {},
    "tag_headers": [
        "Trace-Id",
        "Incoming-Trace-Id"
    ],
    "enable_coprocess_auth": true,
    "custom_middleware": {
        "pre": [
            {
                "name": "TraceID",
                "require_session": false
            }
        ],
        "driver": "grpc"
    }
}

This config returns the mock 200 response but I noticed:

  1. The custom middleware for trace-id is not getting applied to the /hello response.
  2. The /hello response does not show up in our logs like the other endpoints do.

It would be great if you can help me look into these items. Thank you!

Hi @Radhika_Bhatt,

Thank you for your patience.

Yes, the design of Mock response plugin excludes the endpoint that implements it from all other middleware, authentication and Logging.

This is mentioned here.
We understand this doc refers to OAS Mock response, and we will add it to the other Mock Response doc.

1 Like