Layer7 API Management

Expand all | Collapse all

How to retrieve routing URL of specific Web API externally?

Jump to Best Answer
  • 1.  How to retrieve routing URL of specific Web API externally?

    Posted 02-27-2019 03:21 PM

    We mostly use the API Gateway to shield backend web APIs and force users to authenticate when the backend API doesn't offer this kind of security. One of the most common questions we get from our own web developers is "Could you tell me where API XYZ routes to?"

     

    We then have to open the Policy Manager and look it up. We could certainly keep a record of this info elsewhere, but this wouldn't always guaranty that it's the actual routing address and that the tracking file is always up to date.

     

    I thought of creating a simple Web API that our devs could query to return the (or all of) the routing URLs for a certain web API using its resolution path, and using the JDBC query assertion to query the gateway database, but I'm struggling with the formatting of the output in something that's easy to use.

     

    Has anyone else done something similar or would anyone have any suggestions on how to best do this using a Web API?



  • 2.  Re: How to retrieve routing URL of specific Web API externally?

    Posted 02-27-2019 05:19 PM

    I am confused, sounds like you want to provide backend api url to external users. But the purpose of gateway is to hide the backend server, external users only need to know gateway url. Why you want to expose backend url? -- maybe I misunderstand your question ...



  • 3.  Re: How to retrieve routing URL of specific Web API externally?

    Posted 02-27-2019 08:59 PM

    Sorry for the confusion. Most of the systems that use those APIs are internal apps, so the goal is not to "hide" the backend URLs to anyone. The goal is to centralize connections. However, the admins of system A that connects through the API gateway to get to system B, which may belong to another team, often need to validate which backend of system B the API routes to. For example  to confirm which version or which environment it's pointing to.

     

    The search API I thought of would be used by internal admins who need to either document (dynamically) or confirm the routing URL for a given API so they don't need one of the Gateway admins to look it up for them. 



  • 4.  Re: How to retrieve routing URL of specific Web API externally?

    Posted 02-27-2019 11:05 PM

    In your search API, you may,

    select xml from policy where goid in (select policy_goid from published_service where name = ${request.http.parameter.servicename} or routing_uri = ${request.http.parameter.serviceuri});

     

    and then use xpath(//L7p:ProtectedServiceUrl/@stringValue)  to get all the urls in route via http(s) assertion.

     

    But if there is context variable in the route via http(s) assertion, you still cannot get the real url.

     

    sample policy (need to configure ssg jdbc connection)

    <?xml version="1.0" encoding="UTF-8"?>
    <wsp:Policy xmlns:L7p="http://www.layer7tech.com/ws/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
        <wsp:All wsp:Usage="Required">
            <L7p:JdbcQuery>
                <L7p:ConnectionName stringValue="ssg"/>
                <L7p:ConvertVariablesToStrings booleanValue="false"/>
                <L7p:NamingMap mapValue="included">
                    <L7p:entry>
                        <L7p:key stringValue="xml"/>
                        <L7p:value stringValue="xml"/>
                    </L7p:entry>
                </L7p:NamingMap>
                <L7p:SqlQuery stringValue="select xml from policy where goid in (select policy_goid from published_service where name = ${request.http.parameter.servicename} or routing_uri like ${request.http.parameter.serviceuri});"/>
            </L7p:JdbcQuery>
            <L7p:SetVariable>
                <L7p:Base64Expression stringValue="JHtqZGJjUXVlcnkueG1sfQ=="/>
                <L7p:ContentType stringValue="text/xml; charset=utf-8"/>
                <L7p:DataType variableDataType="message"/>
                <L7p:VariableToSet stringValue="resp"/>
            </L7p:SetVariable>
            <L7p:ResponseXpathAssertion>
                <L7p:VariablePrefix stringValue="url"/>
                <L7p:XmlMsgSrc stringValue="resp"/>
                <L7p:XpathExpression xpathExpressionValue="included">
                    <L7p:Expression stringValue="//L7p:ProtectedServiceUrl/@stringValue"/>
                    <L7p:Namespaces mapValue="included">
                        <L7p:entry>
                            <L7p:key stringValue="L7p"/>
                            <L7p:value stringValue="http://www.layer7tech.com/ws/policy"/>
                        </L7p:entry>
                        <L7p:entry>
                            <L7p:key stringValue="s"/>
                            <L7p:value stringValue="http://schemas.xmlsoap.org/soap/envelope/"/>
                        </L7p:entry>
                    </L7p:Namespaces>
                    <L7p:XpathVersion xpathVersion="XPATH_1_0"/>
                </L7p:XpathExpression>
            </L7p:ResponseXpathAssertion>
            <L7p:HardcodedResponse>
                <L7p:Base64ResponseBody stringValue="JHt1cmwucmVzdWx0c30="/>
                <L7p:ResponseContentType stringValue="text/plain; charset=UTF-8"/>
            </L7p:HardcodedResponse>
        </wsp:All>
    </wsp:Policy>


  • 5.  Re: How to retrieve routing URL of specific Web API externally?
    Best Answer

    Posted 02-28-2019 09:41 AM

    I fiddled with it for a while and came up with this policy and attached the XML file to the post:

     

    EDIT: I previously exported the wrong policy by mistake. I will attach the right one when I get back to to office  Apologies... 

     

     

    You'll have to adjust the authentication section to your needs and also change the JDBC connection mapping.

     

    The (STM) Return HTTP Response and Raise Error assertion is a custom encapsulated policy that returns a basic HTTP plain/text status/error and then exits. I've attached it to the post as well in case you're interested. We use it pretty much everywhere.

     

    The policy is limited to 100 results only per search, but you can change that in the JDBC Query assertion (the limit clause) and the Run For Each Item assertion as well. The limit is enforced at every possible place to help performance.

     

    Notice the complex Xpath that looks confusing at first: //L7p:HttpRoutingAssertion[not(L7p:Enabled)]/L7p:ProtectedServiceUrl/@stringValue ... The L7p:Enabled child is only present when it's set to false, otherwise it's absent, which is why I'm only looking for RoutingAssertions that don't have it.

     

    Hope it can help someone else, and thanks for the boost!

    Attachment(s)



  • 6.  Re: How to retrieve routing URL of specific Web API externally?

    Posted 02-28-2019 02:19 PM

    Hi, can you please share your final policy ?

     

    Thanks,



  • 7.  Re: How to retrieve routing URL of specific Web API externally?

    Posted 02-28-2019 03:50 PM

    Done, see above.



  • 8.  Re: How to retrieve routing URL of specific Web API externally?

    Posted 02-28-2019 04:42 PM

    many thanks



  • 9.  Re: How to retrieve routing URL of specific Web API externally?

    Posted 02-28-2019 04:56 PM

    One more thing: If you use a browser to run the query and want to use a percent (%) as a wildcard in the searchstring parameter, use the URL Encoded version %25 ... else the Protect Against SQL Attacks assertion will block it and you'll get a 400 Bad request error...



  • 10.  Re: How to retrieve routing URL of specific Web API externally?

    Posted 03-01-2019 09:35 AM

    Just noticed I made an unnecessary assignation for the ${index} variable. I had issues with the type of the ${row.iterations} used directly as an array index in other places, but turns out the Look Up Item By Index Position assertion takes it directly, so you can remove the Set Context Variable assertion before the Look Up Item... and use ${row.iterations} directly in the Extract value with index value.

     

    Same thing with ${routing_uri} variable. You could use ${row.current} directly in the Return Template Response assertions since it doesn't change before it's called.