API Connect

API Connect

Join this online group to communicate across IBM product users and experts by sharing advice and best practices with peers and staying up to date regarding product enhancements.


#API Connect
#Applicationintegration
#APIConnect
 View Only
Expand all | Collapse all

how to intercept the URL input argument with luascript

  • 1.  how to intercept the URL input argument with luascript

    Posted 07/06/26 09:49 AM

    For example, https://dpnano-weather-sandbox-api-connect-jh.api-n-abxn.trial.apiconnect.ibmappdomain.cloud/1/environment/air-temperature?city=Toronto

    I want to get the input argument: city=Toronto

    How to achieve this via LuaScript? or any other policy can achieve this?



    ------------------------------
    Michael Liu
    ------------------------------


  • 2.  RE: how to intercept the URL input argument with luascript

    Posted 07/06/26 10:39 AM

    Hey Michael,

    No need for LuaScript here, you can use Jsonata and its nano specific extension functions to get the query params.

    I used a log policy to demonstrate but any policy which takes a "dynamicString" can do the same such as Invoke, LoadBalance, Set, ect.

    This is to get a queryParam by name:
          {
            "log" : {
              "messageType" : "jsonata",
              "message" : "$queryParameter(\"request\", \"city\")"
            }
          }
    Results in:
    2026-07-06T14:29:30.093202Z  INFO ThreadId(13) dpn_runtime::actions::log: 46: Toronto

    Or you can get all queryParams from that message:
          {
            "log" : {
              "messageType" : "jsonata",
              "message" : "$queryParameters(\"request\")"
            }
          }
    Which results in:

    2026-07-06T14:34:11.979504Z  INFO ThreadId(12) dpn_runtime::actions::log: 46: [{"city":"Toronto"},{"country":"CA"}]

    And you can use dot notation to get the specific keys if needed:

    "$queryParameters(\"request\").city"


    Let me know if this helps.



    ------------------------------
    Brent Garnett
    Senior Software Developer, DataPower
    ------------------------------



  • 3.  RE: how to intercept the URL input argument with luascript

    Posted 07/06/26 05:24 PM

    Great Tx for your reply, Brent.

    I am sorry that I forgot to mention, I am using a trial account to learn API connect, which has nano dp as the gateway service. That is the reason I tried to use LuaScript to interpret the input argument.

    I tried to upgrade my account to Standard Tier (SaaS), which costs me around $158 + tax monthly which is undertakable. However, Standard Tier (SaaS) might still use nano dp as gateway service. To able to use gateway script capability, I have to upgrade to Premium Tier (SaaS), which costs me around $4500 monthly, and beyond my capability.

    I am wondering if you are using LTE environment to test your policies or on cloud environment.

    I am seeking the possibility which I use someone else's account to learn the api connect, and makes this payable. Do you have any suggestion on this?



    ------------------------------
    Michael Liu
    ------------------------------



  • 4.  RE: how to intercept the URL input argument with luascript

    Posted 07/06/26 06:35 PM

    You can get the query parameter from the request URL in Lua by using the API Connect context variables. For example, in a GatewayScript/Lua policy you can access the query string and parse it:

    local query = context.get("request.querystring")

    -- query will contain: city=Toronto

    local city = string.match(query, "city=([^&]+)")

    print(city)

    If you are using IBM API Connect DataPower Gateway, you can also use the built-in urlopen/context variables depending on your policy type. Another option is to use a Set Variable or GatewayScript policy, which has easier URL parsing support. For multiple parameters or URL encoding, I'd recommend using GatewayScript with JavaScript's URLSearchParams instead of Lua, as it handles query strings more reliably.



    ------------------------------
    Henry Collins
    Web Developer
    Dental Implant Cost Calculator
    ------------------------------



  • 5.  RE: how to intercept the URL input argument with luascript

    Posted 07/06/26 07:20 PM

    Hi, Henry:

    Thanks for your reply.

    It was working with the following response:

    Later on, once I add only first line:

    local response = context:create_message("response")

    response.status = 200

    local request = context:get_message("request")

    local clientId = request.headers["X-IBM-Client-Id"]

    local clientSecret = request.headers["X-IBM-Client-Secret"]

    response.headers["Content-Type"] = "application/json"

    -- Build JSON object
    local out = {
        Weather = {
            ["X-IBM-Client-Id"] = clientId,
            ["X-IBM-Client-Secret"] = clientSecret,
            Location = "Toronto",
            Temperature = "25"
        }
    }

    local query = context.get("request.querystring")

    response.body:write(json.encode(out))
    The result is as:

    So the line as below breaks

    local query = context.get("request.querystring")


    ------------------------------
    Michael Liu
    ------------------------------



  • 6.  RE: how to intercept the URL input argument with luascript

    Posted 07/06/26 07:31 PM

    Thanks for the update.

    From the information you've shared, it looks like the issue is specifically triggered by this line:

    local query = context.get("request.querystring")

    Without this line, the policy returns a 200 OK response. As soon as it's added, even though the query variable isn't used later. the API returns a 500 Internal Server Error.

    This makes me think the issue is related to the context.get("request.querystring") call itself rather than the JSON construction or response handling.



    ------------------------------
    Henry Collins
    Web Developer
    Dental Implant Cost Calculator
    ------------------------------



  • 7.  RE: how to intercept the URL input argument with luascript

    Posted 07/07/26 04:32 PM

    Hi Micahel & Henry, 

    There is no pre-defined assembly context variables in NanoGateway, so context:get("request.querystring") would not work. But you can using set action to set the query parameters into context variable and using context:get() in LuaScript to get the data, for example

    - set:
        valueType: jsonata
        variable:
            name: queryParams
            value: $queryParameters("request")
    - luaScript:
        source: |-
            local params_array = context:get("queryParams")
            local params = {}
            for _, item in ipairs(params_array) do
                for key, value in pairs(item) do
                    params[key] = value
                end
            end
            console.info('request.params.city=' .. params.city)



    ------------------------------
    ------------------------------
    Gary Tu
    Software Developer, DataPower
    ------------------------------
    ------------------------------



  • 8.  RE: how to intercept the URL input argument with luascript

    Posted 07/07/26 04:55 PM

    Gary:

    Thanks for your reply.

    However, it does not satisfy my original requirement: intercept the input argument.

    This is fundamental requirement for any policy sequence.



    ------------------------------
    Michael Liu
    ------------------------------



  • 9.  RE: how to intercept the URL input argument with luascript

    Posted 07/07/26 10:30 PM

    Hi Michael,

    I want to ensure I've understood your requirements correctly. The snippet provided should allow you to extract the 'city' query parameter for LuaScript, as per your original example. Please let me know if this aligns with what you were looking for.



    ------------------------------
    Gary Tu
    Software Developer, DataPower
    ------------------------------



  • 10.  RE: how to intercept the URL input argument with luascript

    Posted 07/08/26 02:26 AM

    Hi, Gary

    Tx for your reply, below is the test result:

    it was working as below:

    You can call it with:

    curl -kv "https://mock-weather-sandbox-api-connect-jh.api-n-abxn.trial.apiconnect.ibmappdomain.cloud/1.0/mockenvironment/mock-temperature" -H "Accept: application/json" -H "X-IBM-Client-Id: 763d3a917b2dbe5a346a19e08a36057f" -H "X-IBM-Client-Secret: 1f395ca3131fbd9dccd8315ea3f6c371"

    However, with the newly added red line which is implemented as below:

    Which has implementation as:

    kind: Set
    apiVersion: api.ibm.com/v1
    metadata:
      name: Mock_QueryParameters
      namespace: Mock_Product_Weather
      version: '1'
      tags: []
      labels:
        gatewayTypes:
          - nano
    spec:
      valueType: jsonata
      variable:
        name: queryParams
        value: $queryParameters("request")

    I got the following result:

    I suspect $queryParameters("request") does not work in nano dp

    Regards,

    Michael Liu



    ------------------------------
    Michael Liu
    ------------------------------



  • 11.  RE: how to intercept the URL input argument with luascript

    Posted 07/08/26 03:41 AM

    Hi Michael,

    I suspect the error is caused by no any query parameters in your test url. You can try to look the logs to verify what kind of error it reports, and also try to append "?city=Toronto&country=CA" in test url to see if it works.



    ------------------------------
    Gary Tu
    Software Developer, DataPower
    ------------------------------



  • 12.  RE: how to intercept the URL input argument with luascript

    Posted 07/09/26 01:06 AM

    Gary:

    Good catch. The internal server was due to the missing input parameters in the Weather Api. Now, I moved the implementation to CityApi which is to call WeatherApi. The Weather Api will returns the city as part of its response

    The policy sequence of city api is as:

    You can see line 16 : 

    - $ref: DPNano_Product_City:DPNano_Set_QueryParameters:1
    which is implemented as:
    The DPNano_LuaScript_Credential is implemented as:
    local request = context:get_message("request")
    request.headers["X-IBM-Client-Id"] = "763d3a917b2dbe5a346a19e08a36057f"
    request.headers["X-IBM-Client-Secret"] = "1f395ca3131fbd9dccd8315ea3f6c371"
    local params_array = context:get("queryParams")
    local paramsstr = ""
    for _, item in ipairs(params_array) do
        for key, value in pairs(item) do
            paramsstr = paramsstr .. key .. "=" .. tostring(value) .. ";"
        end
    end
    request.headers["X-City"] = tostring(paramsstr)

    The response would be:

    However, if hardcoded X-City header as below:

    Then you can see the response

    This proves the context:get("queryParams") returns empty table, which means the queryParams set by below is empty

      variable:
        name: queryParams
        value: $queryParameters("request")
    Please kindly suggest
    Michael Liu

    The command is:

    curl -kv "https://dpnano-weather-sandbox-api-connect-jh.api-n-abxn.trial.apiconnect.ibmappdomain.cloud/1/cityapi/citydetails?city=Toronto" -H "Accept: application/json" -H "X-IBM-Client-Id: 763d3a917b2dbe5a346a19e08a36057f" -H "X-IBM-Client-Secret: 1f395ca3131fbd9dccd8315ea3f6c371"



    ------------------------------
    Michael Liu
    ------------------------------



  • 13.  RE: how to intercept the URL input argument with luascript

    Posted 07/10/26 09:31 AM

    This is a tricky one since it looks like the Set policy is technically running without error, it's just producing an empty result silently instead of throwing anything obvious.
    A couple of things worth isolating before assuming it's a nano DP limitation:

    Add a Log policy right after the Set step, before the LuaScript runs. Log queryParams directly there with jsonata, something like "message": "$queryParams". That way you know for certain whether the Set step itself is populating the variable correctly, or whether the problem is actually happening later when LuaScript tries to read it with context:get("queryParams"). Right now it's not obvious which of the two is failing.
    Also worth double checking scope. If the Set policy and the LuaScript policy are sitting in different flows or different referenced fragments (like your DPNano_Product_City vs DPNano_Set_QueryParameters reference setup), the variable might be getting set in one context and read in another that doesn't share it. Nano gateway context variables can be scoped more strictly than the full DataPower gateway, so a variable set in one $ref block isn't guaranteed to still exist by the time a different $ref block executes, depending on how the assembly is structured.
    One more thing to rule out: try $queryParameters($) instead of $queryParameters("request") in the jsonata expression. In some nano gateway versions the built in extension functions expect the root context rather than an explicit "request" string argument, and passing "request" as a literal string may just resolve to nothing rather than erroring out, which would explain why you get an empty table with no exception.

    If none of that shows anything, it might genuinely be worth opening a support case even on the trial tier, since this smells like either a documentation gap or a real limitation specific to nano DP's jsonata extension functions, not something you're doing wrong on the policy side.



    ------------------------------
    harlay
    ------------------------------



  • 14.  RE: how to intercept the URL input argument with luascript

    Posted 07/12/26 01:47 AM

    Hi, Harlay:

    I got this https://www.ibm.com/docs/en/api-connect/software/12.1.1?topic=policies-set-variable

    It seems like nano datapower does not support this



    ------------------------------
    Michael Liu
    ------------------------------