2

I have a Google Cloud Function which contains multiple modules to be invoked on different paths.

I am using the serverless framework to deploy my functions, but it has the limitation of only one path per function.

I want to use multiple paths in one function just like we can in the AWS serverless framework.

Suppose a user cloud function will have two paths /user/add as well as /user/remove; both the paths should invoke the same function.

Something like this:

serverless.yml

functions:
  user:
    handler: handle
    events:
      - http: user/add
      - http: user/remove

How can I have multiple API endpoints for one GCF?

ggorlen
  • 33,459
  • 6
  • 59
  • 67
Pranay singh
  • 75
  • 1
  • 5

4 Answers4

2

Yes, indeed there is no actual REST service backing up Google Cloud Functions. It uses out of the box HTTP triggers.

To hustle the way around, I'm using my request payload to determine which action to perform. In the body, I'm adding a key named "path".

For example, consider the Function USER.

To add a user:

{
  "path":"add",
  "body":{
    "first":"Jhon",
    "last":"Doe"
  }
}

To remove a user:

{
  "path":"remove",
  "body":{
    "first":"Jhon",
    "last":"Doe"
  }
}

If your operations are purely CRUD, you can use request.method which offers verbs like GET, POST, PUT, DELETE to determine operations.

ggorlen
  • 33,459
  • 6
  • 59
  • 67
Pranay singh
  • 75
  • 1
  • 5
0

Currently, in google allows only one event definition per function is supported. For more

Jishnunand P K
  • 145
  • 1
  • 8
0

GCF doesn't currently support routing within a function. As such, the solution is use-case dependent, but for most simple cases like the example in the question, writing a simple router is a reasonable approach that doesn't involve changing the normal request format.

If parameters or wildcards are involved, consider using route-parser. A deleted answer suggested this app as an example.

The Express request object has a few useful parameters you can take advantage of:

  • req.method which gives the HTTP verb
  • req.path which gives the path without the query string
  • req.query object of the parsed key-value query string
  • req.body the parsed JSON body

Here's a simple proof-of-concept to illustrate:

const routes = {
  GET: {
    "/": (req, res) => {
      const name = (req.query.name || "world");
      res.send(`<!DOCTYPE html>
        <html lang="en"><body><h1>
          hello ${name.replace(/[\W\s]/g, "")}
        </h1></body></html>
      `);
    },
  },
  POST: {
    "/user/add": (req, res) => { // TODO stub
      res.json({
        message: "user added", 
        user: req.body.user
      });
    },
    "/user/remove": (req, res) => { // TODO stub
      res.json({message: "user removed"});
    },
  },
};

exports.example = (req, res) => {
  if (routes[req.method] && routes[req.method][req.path]) {
    return routes[req.method][req.path](req, res);
  }

  res.status(404).send({
    error: `${req.method}: '${req.path}' not found`
  });
};

Usage:

$ curl https://us-east1-foo-1234.cloudfunctions.net/example?name=bob
<!DOCTYPE html>
      <html lang="en"><body><h1>
        hello bob
      </h1></body></html>
$ curl -X POST -H "Content-Type: application/json" --data '{"user": "bob"}' \
> https://us-east1-foo-1234.cloudfunctions.net/example/user/add
{"message":"user added","user":"bob"}

If you run into trouble with CORS and/or preflight issues, see Google Cloud Functions enable CORS?

ggorlen
  • 33,459
  • 6
  • 59
  • 67
0

You could use Firebase Hosting to rewriting URLs.

In your firebase.json file:

"hosting": {
    "rewrites": [
          {
            "source": "/api/v1/your/path/here",
            "function": "your_path_here"
          }
    ]
}

Keep in mind this is a workaround and it has a major drawback: you will pay for double hit. Consider this if your app has to scale.

Fabio Moggi
  • 196
  • 1
  • 2
  • 11