オブジェクト FC アクセスポイントを使用して GetObject API を呼び出すと、Function Compute にバインドされた関数がトリガーされます。関数内で WriteGetObjectResponse API を呼び出して、カスタムデータとレスポンスヘッダーのみを返すことができます。
操作手順
このガイドでは、オブジェクト FC アクセスポイントが、GetObject リクエストに応じて Function Compute 関数を呼び出すように設定されていることを前提としています。Function Compute には WriteGetObjectResponse API オペレーションが含まれており、このオペレーションを使用すると、関数は GetObject の呼び出し元にカスタムレスポンスを提供できます。このオペレーションにより、ステータスコード、レスポンスヘッダー、レスポンス本文を広範囲に制御できます。
WriteGetObjectResponse を使用すると、アプリケーションのロジックに応じて、完全に変換されたオブジェクト、その一部、またはまったく異なるレスポンスを返すことができます。
次の例では、WriteGetObjectResponse API オペレーションの使用方法を説明します。
例:変換された画像による応答
-
GetObject リクエストを処理する関数をコンパイルします。
画像変換などの一部のオペレーションでは、処理する前にソースオブジェクト全体をフェッチする必要がある場合があります。このような場合、
WriteGetObjectResponseを使用して、変換されたオブジェクト全体を 1 つのレスポンスで呼び出し元アプリケーションに返すことができます。Java
OSS SDK for Java のバージョンは 3.17.2 以降である必要があります。
import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.Credentials; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.ObjectMetadata; import com.aliyun.oss.model.VoidResult; import com.aliyun.oss.model.WriteGetObjectResponseRequest; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.util.Scanner; public class Example1 implements StreamRequestHandler { // この例では、China (Qingdao) リージョンのエンドポイントを使用します。 String endpoint = "https://oss-cn-qingdao.aliyuncs.com"; private static int status = 200; public static String convertToString(InputStream inputStream) { Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"); return scanner.hasNext() ? scanner.next() : ""; } @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { Credentials creds = context.getExecutionCredentials(); // context から認証情報を取得します。 OSS ossClient = new OSSClientBuilder().build(endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken()); try { String result = convertToString(inputStream); JSONObject jsonObject = new JSONObject(result); String route = jsonObject.getJSONObject("getObjectContext").getString("outputRoute"); String token = jsonObject.getJSONObject("getObjectContext").getString("outputToken"); // BufferedImage を呼び出して、解像度が 200 × 200 ピクセルの画像オブジェクトを作成し、オブジェクトに赤い四角形を描画します。 // WriteGetObjectResponse リクエストの本文にコンテンツを書き込みます。 BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = image.createGraphics(); graphics.setColor(Color.RED); graphics.fillRect(0, 0, 200, 200); graphics.dispose(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(image, "png", baos); WriteGetObjectResponseRequest writeGetObjectResponseRequest = new WriteGetObjectResponseRequest(route, token, status,new ByteArrayInputStream(baos.toByteArray())); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(baos.size()); writeGetObjectResponseRequest.setMetadata(metadata); VoidResult voidResult = ossClient.writeGetObjectResponse(writeGetObjectResponseRequest); System.out.println("getRequestId:"+voidResult.getRequestId()); System.out.println("status:"+voidResult.getResponse().getStatusCode()); System.out.println("Headers:"+voidResult.getResponse().getHeaders().toString()); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.getErrorMessage()); System.out.println("Error Code: " + oe.getErrorCode()); System.out.println("Request ID: " + oe.getRequestId()); System.out.println("Host ID: " + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getMessage()); } catch (JSONException e) { e.printStackTrace(); } finally { ossClient.shutdown(); } } }Python
OSS SDK for Python のバージョンは 2.18.3 以降である必要があります。
# -*- coding: utf-8 -*- import io from PIL import Image import oss2 import json # この例では、China (Qingdao) リージョンのエンドポイントを使用します。 endpoint = 'http://oss-cn-qingdao.aliyuncs.com' fwd_status = '200' # FC 関数のエントリーポイント def handler(event, context): evt = json.loads(event) creds = context.credentials # セキュリティトークンを必ず含めてください。 auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token) headers = dict() event_ctx = evt["getObjectContext"] route = event_ctx["outputRoute"] token = event_ctx["outputToken"] print(evt) endpoint = route service = oss2.Service(auth, endpoint) # 200x200 ピクセルの画像を作成し、赤色で塗りつぶします。 # 変換したコンテンツを write_get_object_response リクエストの本文に書き込みます。 image = Image.new('RGB', (200, 200), color=(255, 0, 0)) transformed = io.BytesIO() image.save(transformed, "png") resp = service.write_get_object_response(route, token, fwd_status, transformed.getvalue(), headers) print('status: {0}'.format(resp.status)) print(resp.headers) return 'success'Go
OSS SDK for Go のバージョンは 1.2.2 以降である必要があります。
package main import ( "bytes" "context" "fmt" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/fc-runtime-go-sdk/fc" "github.com/aliyun/fc-runtime-go-sdk/fccontext" "image" "image/color" "image/draw" "image/png" ) // GetObjectContext 構造体を定義します。これには、出力ルート (outputRoute) と出力トークン (outputToken) が含まれます。 type GetObjectContext struct { OutputRoute string `json:"outputRoute"` OutputToken string `json:"outputToken"` } // 関数をトリガーするイベントデータを受け取るための StructEvent 構造体を定義します。 type StructEvent struct { GetObjectContext GetObjectContext `json:"getObjectContext"` } // 計算ロジックを処理するための HandleRequest 関数を定義します。 func HandleRequest(ctx context.Context, event StructEvent) error { fmt.Printf("event:%#v\n", event) endpoint := event.GetObjectContext.OutputRoute fwdStatus := "200" fctx, _ := fccontext.FromContext(ctx) // context から認証情報を取得します。 client, err := oss.New(endpoint, fctx.Credentials.AccessKeyId, fctx.Credentials.AccessKeySecret, oss.SecurityToken(fctx.Credentials.SecurityToken), oss.AuthVersion(oss.AuthV4), oss.Region("cn-qingdao")) if err != nil { return fmt.Errorf("client new error: %v", err) } params := map[string]interface{}{} params["x-oss-write-get-object-response"] = nil // 解像度が 200 × 200 ピクセルの画像オブジェクトを作成し、オブジェクトに赤い四角形を描画します。 img := image.NewRGBA(image.Rect(0, 0, 200, 200)) red := color.RGBA{255, 0, 0, 255} draw.Draw(img, img.Bounds(), &image.Uniform{red}, image.Point{}, draw.Src) // 画像を PNG フォーマットで保存します。 var buf bytes.Buffer err = png.Encode(&buf, img) if err != nil { return fmt.Errorf("png encode error: %v", err) } reader := bytes.NewReader(buf.Bytes()) // OSS クライアントを使用して、POST リクエストを送信して変換された画像をアップロードし、x-oss-request-route などの特定の HTTP ヘッダーを指定して、特別な転送リクエストとして識別・処理されるようにします。 headers := make(map[string]string) headers["x-oss-request-route"] = event.GetObjectContext.OutputRoute headers["x-oss-request-token"] = event.GetObjectContext.OutputToken headers["x-oss-fwd-status"] = fwdStatus resp, err := client.Conn.Do("POST", "", "", params, headers, reader, 0, nil) if err != nil { return fmt.Errorf("client conn do error: %v", err) } fmt.Println("status:", resp.StatusCode) fmt.Println(resp.Headers) return nil } // fc.Start(HandleRequest) を呼び出して HandleRequest 関数を登録・実行し、Alibaba Cloud Function Compute のイベントトリガーを待機して処理します。 func main() { fc.Start(HandleRequest) } -
関数をデプロイします。
Java
-
JAR ファイルを解凍します。
-
JAR ファイルを Function Compute コンソールにアップロードします。
-
Function Compute コンソールにログインし、右上隅にある Function Compute 2.0 に戻る をクリックします。
-
左側メニューで、サービスと関数 をクリックします。
-
上部メニューで、[China (Qingdao)] リージョンを選択します。
-
[サービス] ページで、サービスをクリックし、Java 11 ランタイムを使用する関数をクリックします。
-
関数の詳細ページで、 を選択します。
-
ダイアログボックスで、パッケージ化された JAR ファイルを選択し、ファイルが選択された後に関数をデプロイします。 を選択し、保存してデプロイ をクリックします。
-
-
サンプル関数に基づいて関数ハンドラを変更します。
-
関数の詳細ページで、設定 タブをクリックします。
-
[環境情報] セクションで、変更 をクリックします。
-
リクエストハンドラー を変更します。
ランタイムが Java の場合、現在の値は
[package].[class]::[method]というフォーマットです。例えば、現在の値がexample.HelloFC::handleRequestの場合、example パッケージの HelloFC クラスの handleRequest メソッドが呼び出されます。この例のコードはデフォルトパッケージにあるため、ハンドラをExample1::handleRequestに変更します。
-
Python
-
Function Compute コンソールにログインし、右上隅にある Function Compute 2.0 に戻る をクリックします。
-
左側メニューで、サービスと関数 をクリックします。
-
上部メニューで、[China (Qingdao)] リージョンを選択します。
-
[サービス] ページで、サービスをクリックし、Python 3.10 ランタイムを使用する関数をクリックします。
-
関数の詳細ページで、コード タブをクリックし、 を選択します。
-
TERMINAL パネルで、次のコマンドを実行して OSS SDK for Python のバージョンを更新します。
pip install oss2 -t . -
index.py の内容を、GetObject リクエストを処理するための Python 関数サンプルコードに置き換えてから、[関数のデプロイ] をクリックします。
Go
-
OSS SDK for Go のランタイム環境をインストールします。
-
コードパッケージをコンパイルします。詳細については、「Linux または macOS でのコードのコンパイルとパッケージ化」をご参照ください。
コンパイルの前に、main.go ファイルの内容を、前の手順で示した GetObject リクエスト処理用のサンプルコードに置き換えます。
-
コンパイルされたバイナリファイルを ZIP パッケージとして Go 1 ランタイム環境 を使用する関数にアップロードし、関数ハンドラーを設定します。詳細については、「FC 関数ハンドラーを設定する」をご参照ください。
-