Skip to content
This repository has been archived by the owner on May 15, 2019. It is now read-only.

Inconsistent behaviour for parsing path and path params #46

Closed
MartinSahlen opened this issue Feb 28, 2017 · 11 comments
Closed

Inconsistent behaviour for parsing path and path params #46

MartinSahlen opened this issue Feb 28, 2017 · 11 comments
Labels
Milestone

Comments

@MartinSahlen
Copy link

MartinSahlen commented Feb 28, 2017

Description

The emulator does not parse the path and path params. I am implementing a simple routing mechanism that relies on getting the path minus the function name. I have looked somewhat in the emulator source and it seems that somewhere around here, the path is not forwarded to the cloud function handler: https://github.com/GoogleCloudPlatform/cloud-functions-emulator/blob/master/src/supervisor/index.js#L122

NB: query params seems to work as expected.

Steps to reproduce

I have created a function called helloGO that has a route called hello/:ergegr, that is a route with prefix path hello and path param ergegr. It should return a request object that has a params key containing an object with a key ergegr and a list of the params as key.

  1. deploy a function that just returns the express request to the emulator
  2. deploy a function that just returns the express request to the real cloud function
  3. make a request to each of the endpoints (they should be the same).

See screenshot of 1):
screen shot 2017-02-28 at 14 22 18

See screenshot of 2):
screen shot 2017-02-28 at 14 21 16

I dont know if this violates the intention of cloud functions but I bet at least some would agree that being able to let an endpoint / microservice handle at least some cases in in idiomatic way would be great. By idiomatic I mean paths, not having to construct huge query structures.

Thanks!

@jmdobry
Copy link
Contributor

jmdobry commented Feb 28, 2017

a function called helloGO that has a route called hello/:ergegr

I don't understand the "route" that you're referring to. How is it defined? Can you post your function code?

@MartinSahlen
Copy link
Author

So, I'm sorry, this was just my local testing and the names are stupid. I am actually writing go and converting to js (does not really matter in this case), let me explain by showing the source:

//EntryPoint is the main handler and entrypoint for the google cloud function
func EntryPoint(req, res *js.Object) {

	r := router.New(rootHandler)
	r.Handle(http.MethodGet, "/hello/:ergegr", helloHandler)
	r.Handle(http.MethodPost, "/site", websiteHandler)
	//r.Handle(http.MethodGet, "/bq", helloBigQuery)

	r.Serve(express.NewResponse(res), express.NewRequest(req))
}

func main() {
	if googleCloudFunctionName == "" {
		googleCloudFunctionName = "helloGO"
	}
	js.Module.Get("exports").Set(googleCloudFunctionName, EntryPoint)
}

So, the google cloud function executor in the cloud passes on the the path (meaning the part of the path that comes after http://localhost:8010/<project-name>/us-central1/helloGO) to every of the request (https://expressjs.com/en/api.html#req.path) along with the request object so that i can utilize this for my "internal routing" by parsing it according to my own rules / regexes.

While the google cloud emulator gives me /<project-name>/us-central1/helloGO for my path no matter if I write /<project-name>/us-central1/helloGO/hello/my-path-param.

Sorry for confusing with my testing code. As stated, even though I'm doing this in Go for testing, the principle is the same, the path part is not handled the same way.

@MartinSahlen
Copy link
Author

I think the simplest example of the inconsistency can be reproduced by creating a http function with this signature:

exports.helloWorld = function helloWorld (req, res) {
  res.send(req.path);
};

@MartinSahlen
Copy link
Author

If this function is deployed to the emulator vs the cloud, you will get different paths back. For my case, where I might want to use this path for something, e.g. my internal routing it breaks in the emulator.

@MartinSahlen
Copy link
Author

So, as I see it, please disregard my first two comments. They just confuse more than explain or clarify. The real consise issue is really summarized in my two above posts.

@jamesdaniels
Copy link

jamesdaniels commented Feb 28, 2017

Oh, I think I see what you mean @MartinSahlen

If you deploy helloWorld to production and hit /helloWorld/blah the path reports back as /helloWorld/blah.

If in the emulator if you hit http://localhost:8010/jamesdaniels-scratch/us-central1/helloWorld/blah it only reports /us-central1/helloWorld as the path.

Is this what you're reporting?

@jmdobry
Copy link
Contributor

jmdobry commented Feb 28, 2017

Okay, I can now reproduce the issue. I'm working on a fix.

@jmdobry jmdobry self-assigned this Feb 28, 2017
@jmdobry jmdobry added the bug label Feb 28, 2017
@MartinSahlen
Copy link
Author

thanks! and yes @jamesdaniels that is exactly what I was trying to say. Can't believe it took that many posts to say 😂

@jmdobry
Copy link
Contributor

jmdobry commented Feb 28, 2017

Fixed in 1.0.0-alpha.5

@jmdobry jmdobry added this to the 1.0.0 milestone Mar 1, 2017
@MartinSahlen
Copy link
Author

@jmdobry This issue is still not resolved, I'm sorry, it's probably due to my bad explaining. The emulator and production environment still gives different paths. The emulator gives /helloWorld/hi for the path while the production environment gives /hi for the simple function

exports.helloWorld = function helloWorld (req, res) {
  res.send(req.path);
};

The emulator needs to "chop off" the function name from the path before forwarding it to the handler cloud function.

@jmdobry jmdobry reopened this Mar 1, 2017
@jmdobry
Copy link
Contributor

jmdobry commented Mar 1, 2017

Ah I see, will fix.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants