In Cloud Run, you write an HTTP function when you want to invoke a function through an HTTP(S) request. To allow for HTTP semantics, you use the Function Framework and specify the HTTP Function signature to accept HTTP-specific arguments.
Implement HTTP handler functions
The following example shows a basic HTTP function source file for each runtime. See Source directory structure for information about where to locate your source code.
Node.js
const functions = require('@google-cloud/functions-framework');
// Register an HTTP function with the Functions Framework
functions.http('myHttpFunction', (req, res) => {
// Your code here
// Send an HTTP response
res.send('OK');
});
In Node.js, you register an HTTP handler function with the Functions Framework for Node.js. Your HTTP handler function must be an Express middleware function that accepts the request and response arguments and sends an HTTP response.
Cloud Run automatically parses the request body for you based on the
request's Content-Type
header using
body-parser
,
so you can access the req.body
and req.rawBody
objects in your HTTP handler.
The
function entry point
is the name with which the handler is registered with the Functions Framework.
In this example, the entry point is myHttpFunction
.
Python
import functions_framework
# Register an HTTP function with the Functions Framework
@functions_framework.http
def my_http_function(request):
# Your code here
# Return an HTTP response
return 'OK'
In Python, you register an HTTP handler function with the Functions Framework for Python. Your HTTP handler function must accept a Flask request object as an argument and return a value that Flask can convert into an HTTP response object.
The
function entry point
is the name with which the handler is registered with the Functions Framework.
In this example, the entry point is my_http_function
.
Go
package myhttpfunction
import (
"fmt"
"net/http"
"github.com/GoogleCloudPlatform/functions-framework-go/functions"
)
func init() {
// Register an HTTP function with the Functions Framework
functions.HTTP("MyHTTPFunction", myHTTPFunction)
}
// Function myHTTPFunction is an HTTP handler
func myHTTPFunction(w http.ResponseWriter, r *http.Request) {
// Your code here
// Send an HTTP response
fmt.Fprintln(w, "OK")
}
In Go, you register an HTTP handler function with the
Functions Framework for Go
in your init()
function. Your HTTP handler function must use the standard
http.HandlerFunc
interface to send an HTTP response.
The
function entry point
is the name with which the handler is registered with the Functions Framework.
In this example, the entry point is MyHTTPFunction
.
Your HTTP handler function must implement the standard
http.HandlerFunc
interface. It accepts an http.ResponseWriter interface that your function uses
to create a reply to the request, and a pointer to an
http.Request struct containing the
details of the inbound HTTP request.
Java
package myhttpfunction;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
// Define a class that implements the HttpFunction interface
public class MyHttpFunction implements HttpFunction {
// Implement the service() method to handle HTTP requests
@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
// Your code here
// Send an HTTP response
response.getWriter().write("OK");
}
}
In Java, you use the
Functions Framework Java API
to implement an HTTP handler class with the
HttpFunction
interface. The service()
method must send an HTTP response.
The
function entry point
is the fully-qualified name of the HTTP handler class, including the package
name. In this example, the entry point is myhttpfunction.MyHttpFunction
.
Your service
method receives an
HttpRequest
object describing the inbound HTTP request, and an
HttpResponse
object that your function populates with a response message.
.NET
using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace MyProject
{
// Define a class that implements the IHttpFunction interface
public class MyHttpFunction : IHttpFunction
{
// Implement the HandleAsync() method to handle HTTP requests
public async Task HandleAsync(HttpContext context)
{
// Your code here
// Send an HTTP response
await context.Response.WriteAsync("OK");
}
}
}
In .NET runtimes, you use the
Functions Framework for .NET
to implement an HTTP handler class with the
IHttpFunction
interface. The HandleAsync()
method accepts a standard ASP.NET
HttpContext
object as an argument and must send an HTTP response.
The function entry point
is the fully-qualified name of the HTTP handler class, including the
namespace. In this example, the entry point is MyProject.MyHttpFunction
.
Ruby
require "functions_framework"
# Register an HTTP function with the Functions Framework
FunctionsFramework.http "my_http_function" do |request|
# Your code here
# Return an HTTP response
"OK"
end
In Ruby, you register an HTTP handler function with the Functions Framework for Ruby. Your HTTP handler function must accept a Rack request object as an argument and return a value that can be used as an HTTP response.
The
function entry point
is the name with which the handler is registered with the Functions Framework.
In this example, the entry point is my_http_function
.
PHP
<?php
use Google\CloudFunctions\FunctionsFramework;
use Psr\Http\Message\ServerRequestInterface;
// Register an HTTP function with the Functions Framework
FunctionsFramework::http('myHttpFunction', 'myHttpHandler');
// Define your HTTP handler
function myHttpHandler(ServerRequestInterface $request): string
{
// Your code here
// Return an HTTP response
return 'OK';
}
In PHP, you register an HTTP handler function with the
Functions Framework for PHP.
Your HTTP handler function must accept an argument that implements the PSR-7
ServerRequestInterface
interface, and must return an HTTP response as either a string or an object
that implements the PSR-7
ResponseInterface
interface.
The
function entry point
is the name with which the handler is registered with the Functions Framework.
In this example, the entry point is myHttpFunction
.
HTTP request and responses
When you register an HTTP handler function with the Functions Framework, your HTTP handler can inspect the request method and perform different actions based on the method.
When you configure an event provider to send HTTP requests to your Cloud Run function, your function sends an HTTP response. If the function creates background tasks (such as with threads, futures, JavaScript Promise objects, callbacks, or system processes), you must terminate or otherwise resolve these tasks before sending an HTTP response. Any tasks not terminated before the HTTP response is sent might not be completed, and might cause undefined behavior.
Handling CORs / CORS support
Cross-Origin Resource Sharing (CORS) is a way to let applications running on one domain access resources from another domain. For example, you might need to let your domain make requests to the Cloud Run functions domain to access your function.
To allow cross-origin requests to your function, set the
Access-Control-Allow-Origin
header as appropriate on your HTTP response. For
preflighted cross-origin requests,
you must respond to the preflight OPTIONS
request with a 204
response code
and additional headers.
Node.js
Python
Go
Java
.NET
Ruby
PHP
If CORS is not set up properly, you might see errors like the following:
XMLHttpRequest cannot load https://YOUR_FUNCTION_URL. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://YOUR_DOMAIN' is therefore not allowed access.
CORS limitations
For preflighted cross-origin requests, preflight OPTIONS requests are sent without an Authorization header, so they will be rejected on all HTTP functions that require authentication. Because the preflight requests fail, the main requests will also fail. To work around this limitation, use one of the following options:
- Allow unauthenticated invocations of your function.
- Host your web app and Cloud Run on the same domain to avoid CORS. You can do this by integrating Firebase Hosting with Cloud Run functions.