How to propagate request path to backend

946 views
Skip to first unread message

Maarten Dirkse

unread,
Sep 30, 2020, 5:31:20 AM9/30/20
to api-gateway-users
Hi,

I've got an API Gateway that is configured to send traffic to my Cloud Run backend as follows (non-relevant details anonymized):

swagger: '2.0'
info:
  description: Foo
  title: Foo API
  version: 0.5.0
schemes:
  - https
produces:
  - application/json
securityDefinitions:
  firebase:
    authorizationUrl: ''
    flow: 'implicit'
    type: 'oauth2'
    x-google-issuer: 'https://securetoken.google.com/foo'
    x-google-audiences: 'foo'
paths:
  /v1/profile:
    get:
      produces:
        - application/json
      parameters: []
      responses:
        '200':
          description: OK
          schema:
            $ref: '#/definitions/Profile'
      security:
        - firebase: []
      operationId: profile-get
      x-google-backend:
        address: 'https://foo.a.run.app'
definitions:
  Profile:
    properties:
      club:
        format: int32
        type: integer
      email:
        type: string
      id:
        type: string
      name:
        type: string
      roles:
        items:
          type: string
        type: arrayhttps://foo.a.run.app
    type: object

The API gateway passes the request to the backend, but does so in a weird way. If I get <api-url>/profile My backend reports that the path is http://foo.a.run.app (notice no 's') which obviously doesn't map to any resource I have defined there. If I look at the Cloud Run logs for the request I see:

httpRequest: {
  requestMethod: "GET"
  requestUrl: "https://foo.a.run.app/"
  requestSize: "4147"
  status: 404
  responseSize: "371"
  userAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
  remoteIp: "<remote ip>"
  referer: "https://foo.app"
  serverIp: "216.239.36.53"
  latency: "0.077308090s"
  protocol: "HTTP/1.1"
}

It seems that the request path is not being passed on at all. Have I misconfigured something?

Regards,
Maarten

Maarten Dirkse

unread,
Sep 30, 2020, 5:32:40 AM9/30/20
to api-gateway-users
Please disregard the errant https://foo.a.run.app in the definitions block, it was a copy-past error.

Gagandeep Toor

unread,
Sep 30, 2020, 10:25:40 AM9/30/20
to api-gateway-users
status: 404 > By using case-sensitive routing, your API returns an HTTP status code of 404 when the method requested in the URL doesn't match the API method name listed in your OpenAPI specification.

Additionally, Google Groups hosts discussion forums where you're likely to find information like service status updates and release notes, and ranging from book recommendations to creative shortcuts. For technical issues, please try Stack Exchange sites.

Josh Einhorn

unread,
Sep 30, 2020, 11:21:02 AM9/30/20
to Gagandeep Toor, api-gateway-users
Though Gagandeep's suggestion to post on Stack Exchange is accurate, this one is relatively simple:

The fix is simple, though admittedly not intuitive. See our docs on x-google-backend, especially the note below the description

tl;dr - if you set x-google-backend in an operation (as you have done), the "path translation" setting is overridden such that requests are transformed from {address}/{path} to {host}?{transformed_path_variables} e.g. given address api.foo.com/v1, then api.foo.com/v1/pets/spot will be transformed to api.foo.com/v1?petId=spot. In your case, since you have no path variables, it is just stripping off the path (/v1/profile) entirely and not appending any query params.

There are two different fixes:

1. Move your x-google-backend declaration to the "top-level" of your OAS Document
2. Add path_translation: APPEND_PATH_TO_ADDRESS to the existing operation-level x-google-backend block.

Another thing though:
My backend reports that the path is http://foo.a.run.app (notice no 's')
What is reporting this? The Cloud Run access log, the API Gateway access log, or something else? We're not sending unencrypted traffic, so this seems like a logging issue.

-Josh

--
You received this message because you are subscribed to the Google Groups "api-gateway-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-gateway-us...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/api-gateway-users/43d1e231-a818-4bc0-baf5-9b5f5804d405n%40googlegroups.com.


--
Josh Einhorn | Software Engineer | joshe...@google.com | 1-215-837-1102

Maarten Dirkse

unread,
Sep 30, 2020, 5:19:51 PM9/30/20
to api-gateway-users
Hi Josh,

Thanks for the tip! I hadn't checked the docs on x-google-backend in-depth because I'm still a little bit hazy as to what is part of Endpoints and what is API Gateway. Sometimes it seems the functionality is similar (especially when it comes to OpenAPI specs) but then at other times they do different things (like how Endpoints serves up a X-Endpoint-API-UserInfo header when you've authenticated via Firebase, but the API Gateway does not).

Anyway, moving x-google-backend to the top level did the trick. I knew that was possible, but was hesitant to do so at first because the whole point of the API Gateway is that you can declare different backends for different paths. But I guess you can override the top-level one with path-specific ones?

About the missing 's': it's my cloud run service (a Quarkus service in my case) that's reporting this. I had it spit out the UriInfo object that it receives and it was as follows:
{
  absoluteString: "http://foo.a.run.app/"
  encodedMatchedPaths: [0]
  matchedUris: null
  absolutePath: null
  queryParameters: null
  encodedPath: "/"
  encodedQueryParameters: null
  matchingPath: "/"
  pathStart: 40
  baseURI: null
  encodedPathParameters: null
  encodedPathSegments: [0]
  encodedMatchedUris: null
  pathSegments: [0]
  ancestors: null
  pathParameterPathSegments: null
  path: "/"
  queryIdx: -1
  pathParameters: null
  encodedPathParameterPathSegments: null
  requestURI: null
  contextPath: "/"
}

You can see it's http, and not https, but I honestly don't know if that 's' gets lost somewhere on the Quarkus side of things. All the request logging done by the API Gateway and Cloud Run all report https.

Thanks for your help,
Maarten

Josh Einhorn

unread,
Sep 30, 2020, 5:55:07 PM9/30/20
to Maarten Dirkse, api-gateway-users
I'm still a little bit hazy as to what is part of Endpoints and what is API Gateway
This is a completely valid concern and something we are actively working on addressing! In general, you should be able rely primarily on the API Gateway docs for interacting with the API Gateway service, and rely on the Endpoints docs for the configuration model and the behavior of the proxy. The relevant Endpoints docs should be specifically referenced by the API Gateway docs (which includes the OpenAPI extensions).

But I guess you can override the top-level one with path-specific ones
Yep that's right.

About the missing 's': it's my cloud run service (a Quarkus service in my case) that's reporting this. I had it spit out the UriInfo object that it receives and it was as follows:
I see. Since you're logging from inside your container, this is a quirk (no pun intended) of Cloud Run; Cloud Run itself terminates TLS (the 's' part) and then forwards plain HTTP to your container (otherwise you'd have to terminate TLS yourself inside your container).

-Josh

Reply all
Reply to author
Forward
0 new messages