編寫 HTTP 函式
在 Cloud Run 函式中,如要透過 HTTP(S) 要求叫用函式,請使用 HTTP 函式。如要允許 HTTP 語意,HTTP 函式簽章會接受 HTTP 專屬引數。
導入作業
以下範例顯示各個執行階段的基本 HTTP 函式來源檔案。如要瞭解原始碼的位置,請參閱「來源目錄結構」。
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');
});
在 Node.js 中,您可以使用 Node.js 適用的 Functions Framework 註冊 HTTP 處理常式函式。HTTP 處理常式函式必須是 Express 中介軟體函式,可接受要求和回應引數,並傳送 HTTP 回應。
Cloud Run functions 會根據要求的 Content-Type
標頭,使用 body-parser
自動剖析要求主體,因此您可以在 HTTP 處理常式中存取 req.body
和 req.rawBody
物件。
函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 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'
在 Python 中,您可以使用 Python 適用的 Functions Framework 註冊 HTTP 處理常式函式。HTTP 處理常式函式必須接受 Flask 要求物件做為引數,並傳回 Flask 可轉換為 HTTP 回應物件的值。
函式進入點是向 Functions Framework 註冊的處理常式函式名稱。在本範例中,進入點為 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")
}
在 Go 中,您可以在 init()
函式中,使用 Go 適用的 Functions Framework 註冊 HTTP 處理常式函式。HTTP 處理常式函式必須使用標準 http.HandlerFunc
介面傳送 HTTP 回應。
函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 MyHTTPFunction
。
HTTP 處理常式函式必須實作標準的 http.HandlerFunc
介面。這個函式會接受 http.ResponseWriter 介面,您的函式會使用這個介面建立要求的回覆,以及指向 http.Request 結構的指標,其中包含傳入 HTTP 要求的詳細資料。
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");
}
}
在 Java 中,您可以使用 Functions Framework Java API,透過 HttpFunction
介面實作 HTTP 處理常式類別。service()
方法必須傳送 HTTP 回應。
函式進入點是 HTTP 處理常式類別的完整名稱,包括套件名稱。在本範例中,進入點為 myhttpfunction.MyHttpFunction
。
您的 service
方法會收到 HttpRequest
物件,其中說明傳入的 HTTP 要求,以及 HttpResponse
物件,您的函式會使用回應訊息填入該物件。
C#
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");
}
}
}
在 .NET 執行階段中,您可以使用 .NET 適用的 Functions Framework,透過 IHttpFunction
介面實作 HTTP 處理常式類別。HandleAsync()
方法會接受標準 ASP.NET HttpContext
物件做為引數,且必須傳送 HTTP 回應。
函式進入點是 HTTP 處理常式類別的完整名稱,包括命名空間。在本範例中,進入點為 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
在 Ruby 中,您可以使用 Ruby 適用的 Functions Framework 註冊 HTTP 處理常式函式。您的 HTTP 處理常式函式必須接受 Rack 要求物件做為引數,並傳回可用於 HTTP 回應的值。
函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 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';
}
在 PHP 中,您可以使用 PHP 適用的 Functions Framework 註冊 HTTP 處理常式函式。HTTP 處理常式函式必須接受實作 PSR-7 ServerRequestInterface
介面的引數,且必須以字串或實作 PSR-7 ResponseInterface
介面的物件形式,傳回 HTTP 回應。
函式進入點是處理常式向 Functions Framework 註冊的名稱。在本範例中,進入點為 myHttpFunction
。
HTTP 要求和回應
HTTP 函式會接受「HTTP 觸發條件」頁面列出的 HTTP 要求方法。HTTP 處理常式可以檢查要求方法,並根據方法執行不同的動作。
函式必須傳送 HTTP 回應。如果函式會建立背景工作 (例如使用執行緒、Future、JavaScript Promise
物件、回呼或系統程序),您必須先終止或解決這些工作,才能傳送 HTTP 回應。如果 HTTP 回應傳送前未終止任何工作,這些工作可能無法完成,並可能導致未定義的行為。
如要進一步瞭解 HTTP 函式和相關選項,請參閱 HTTP 觸發條件。
處理 CORS
跨源資源共享 (CORS) 可讓在一個網域上執行的應用程式存取另一個網域的資源。舉例來說,您可能需要允許網域對 Cloud Run 函式網域提出要求,才能存取函式。
如果 CORS 設定不正確,可能會看到下列錯誤:
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.
如要允許對函式提出跨來源要求,請在 HTTP 回應中適當設定 Access-Control-Allow-Origin
標頭。對於預檢跨來源要求,您必須以 204
回應代碼和額外標頭,回應預檢 OPTIONS
要求。
Node.js
Python
Go
Java
C#
using Google.Cloud.Functions.Framework; using Microsoft.AspNetCore.Http; using System.Net; using System.Threading.Tasks; namespace Cors; // For more information about CORS and CORS preflight requests, see // https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request. public class Function : IHttpFunction { public async Task HandleAsync(HttpContext context) { HttpRequest request = context.Request; HttpResponse response = context.Response; // Set CORS headers // Allows GETs from any origin with the Content-Type // header and caches preflight response for 3600s response.Headers.Append("Access-Control-Allow-Origin", "*"); if (HttpMethods.IsOptions(request.Method)) { response.Headers.Append("Access-Control-Allow-Methods", "GET"); response.Headers.Append("Access-Control-Allow-Headers", "Content-Type"); response.Headers.Append("Access-Control-Max-Age", "3600"); response.StatusCode = (int) HttpStatusCode.NoContent; return; } await response.WriteAsync("CORS headers set successfully!", context.RequestAborted); } }
Ruby
PHP
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use GuzzleHttp\Psr7\Response; function corsEnabledFunction(ServerRequestInterface $request): ResponseInterface { // Set CORS headers for preflight requests // Allows GETs from any origin with the Content-Type header // and caches preflight response for 3600s $headers = ['Access-Control-Allow-Origin' => '*']; if ($request->getMethod() === 'OPTIONS') { // Send response to OPTIONS requests $headers = array_merge($headers, [ 'Access-Control-Allow-Methods' => 'GET', 'Access-Control-Allow-Headers' => 'Content-Type', 'Access-Control-Max-Age' => '3600' ]); return new Response(204, $headers, ''); } else { return new Response(200, $headers, 'Hello World!'); } }
CORS 限制
如果是預檢的跨來源要求,預檢 OPTIONS
要求會在沒有 Authorization
標頭的情況下傳送,因此會在所有需要驗證的 HTTP 函式中遭到拒絕。由於預檢要求失敗,主要要求也會失敗。如要避開這項限制,請採取下列任一做法:
- 允許未經驗證的叫用函式。
- 將網頁應用程式和 Cloud Run 函式託管在相同網域,避免發生 CORS 問題。 如要這麼做,請整合 Firebase 託管與 Cloud Run 函式。
後續步驟
- 進一步瞭解 HTTP 觸發條件。
- 瞭解如何部署 Cloud Run 函式。