すべてのプロダクト
Search
ドキュメントセンター

Function Compute:ハンドラー

最終更新日:Jul 24, 2024

Javaハンドラーを使用して、受信したイベントに応答し、対応するビジネスロジックを実行できます。 このトピックでは、Javaハンドラーの概念と機能について説明し、例を示します。

説明

HTTPトリガーまたはカスタムドメイン名を使用して関数にアクセスする場合は、HTTP応答を定義する前にリクエスト構造体を取得してください。 詳細については、「HTTPトリガーを使用した関数の呼び出し」をご参照ください。

ハンドラーとは何ですか?

FC内の関数のハンドラは、関数コード内の要求を処理するために使用される。 関数が呼び出されると、Function Computeは設定したハンドラーを使用してリクエストを処理します。

function Computeコンソールhandlerパラメーターを指定することで、関数のハンドラーを設定できます。 Java関数のハンドラは、[パッケージ名].[クラス名]::[メソッド名] の形式に従います。 たとえば、パッケージの名前がexample、クラスタイプがHelloFC、メソッドがhandleRequestの場合、ハンドラーはexample.HelloFC::handleRequestのように設定できます。

ハンドラーの設定は、Function Computeの設定仕様に準拠している必要があります。 設定の仕様は、ハンドラーの種類によって異なります。

Handlerインターフェイス

プログラミングにJavaを使用する場合は、Function Computeが提供するインターフェースクラスを実装する必要があります。 fc-java-coreライブラリは、ハンドラーの次のインターフェイスを定義します。

  • StreamRequestHandler

    ストリームを使用して入力イベントデータを受信し、応答を返します。 入力ストリームから入力データを読み取り、実行結果を出力ストリームに書き込む必要があります。

  • PojoRequestHandler

    ジェネリック型を使用して入力イベントを受信し、応答を返します。 ハンドラーの入出力データの種類をカスタマイズできます。 入力データと出力データの両方がPlain Old Java Object (POJO) 型である必要があります。

StreamRequestHandler

次のサンプルコードは、単純なStreamRequestHandlerを示しています。

package example;

import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class HelloFC implements StreamRequestHandler {

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        outputStream.write(new String("hello world").getBytes());
    }
}           
  • パッケージ名とクラス名

    Javaは、パッケージに基づく実行方法が他のプログラミング言語とは異なります。 上記のサンプルコードでは、ハンドラーはexample.HelloFC::handleRequestです。 exampleはパッケージ名、HelloFCはクラス名、handleRequestはクラスメソッドを示します。

    説明

    パッケージ名とクラス名はカスタマイズできます。 ただし、名前は関数設定のHandlerパラメーターの値と一致している必要があります。 Handlerの設定方法の詳細については、「イベント関数の作成」をご参照ください。

  • 実装インターフェイス

    コードは、Function Computeで定義されているインターフェイスを実装する必要があります。 上記のサンプルコードでは、StreamRequestHandlerが実装されています。 inputStreamパラメーターは、関数を呼び出したときにFunction Computeに渡されるデータです。 outputStreamパラメーターは、関数の実行結果を返すために使用されます。

  • 背景

    Contextパラメーターには、リクエストIDや一時的なAccessKeyペアなど、関数の実行時情報が含まれます。 タイプはcom.aliyun.fc.ru ntime.Contextです。 詳細は、「コンテキスト」をご参照ください。

  • 戻り値

    StreamRequestHandlerを実装する関数は、outputStreamパラメーターを使用して実行結果を返します。

  • インタフェースライブラリ

    com.aliyun.fc.ru ntimeパッケージの依存関係は、次のサンプルコードのpom.xmlファイルで参照できます。

    <dependency>
        <groupId>com.aliyun.fc.runtime</groupId>
        <artifactId>fc-java-core</artifactId>
        <version>1.4.1</version>
    </dependency>           

    Mavenリポジトリにアクセスして、fc-java-coreパッケージの最新バージョンを取得できます。

関数を作成する前に、コードとその依存関係fc-java-coreをJARファイルに圧縮する必要があります。 コードと依存関係を圧縮する方法の詳細については、「コードパッケージのコンパイルとデプロイ」をご参照ください。

PojoRequestHandler

次のサンプルコードは、単純なPojoRequestHandlerを示しています。 SimpleRequestオブジェクトはJSONシリアル化をサポートする必要があります。 たとえば、POJOを使用できます。

// HelloFC.java
package example;

import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.PojoRequestHandler;

public class HelloFC implements PojoRequestHandler<SimpleRequest, SimpleResponse> {

    @Override
    public SimpleResponse handleRequest(SimpleRequest request, Context context) {
        String message = "Hello, " + request.getFirstName() + " " + request.getLastName();
        return new SimpleResponse(message);
    }
}            
// SimpleRequest.java
package example;

public class SimpleRequest {
    String firstName;
    String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public SimpleRequest() {}
    public SimpleRequest(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}            
// SimpleResponse.java
package example;

public class SimpleResponse {
    String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public SimpleResponse() {}
    public SimpleResponse(String message) {
        this.message = message;
    }
}            

次のサンプルコードでは、input eventパラメーターについて説明します。

{
  "firstName": "FC",
  "lastName": "aliyun"
}            

例: HTTPトリガーを使用して関数を呼び出す

サンプルコード

上記のサンプルコードでは、HTTPTriggerEvent.javaがHTTPトリガーのリクエスト形式を宣言し、HTTPTriggerResponse.javaがHTTPトリガーのレスポンス形式を宣言しています。 HTTPトリガーのリクエストとレスポンスの形式の詳細については、「HTTPトリガーを使用して関数を呼び出す」をご参照ください。

HTTPTriggerEvent.java

package example;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder(setterPrefix = "with")
public class HTTPTriggerEvent {
    private String version;
    private String rawPath;
    private Map<String, String> headers;
    private Map<String, String> queryParameters;
    private RequestContext requestContext;

    @JsonProperty("isBase64Encoded")
    private boolean IsBase64Encoded;
    private String body;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder(setterPrefix = "with")
    public static class RequestContext {
        private String accountId;
        private String domainName;
        private String domainPrefix;
        private HttpInfo http;
        private String requestId;
        private String time;
        private String timeEpoch;

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @Builder(setterPrefix = "with")
        public static class HttpInfo {
            private String method;
            private String path;
            private String protocol;
            private String sourceIp;
            private String userAgent;
        }
    }

}

HTTPTriggerResponse.java

package example;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Map;

import com.fasterxml.jackson.annotation.JsonProperty;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder(setterPrefix = "with")
public class HTTPTriggerResponse {
    private int statusCode;
    private Map<String, String> headers;

    @JsonProperty("isBase64Encoded")
    private boolean IsBase64Encoded;
    private String body;
}

App.javaは、関数のエントリクラスを定義します。

アプリ. java

package example;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.PojoRequestHandler;

/**
 * HTTP Trigger demo
 *
 */
public class App implements PojoRequestHandler<HTTPTriggerEvent, HTTPTriggerResponse> {

    @Override
    public HTTPTriggerResponse handleRequest(HTTPTriggerEvent request, Context context) {
        context.getLogger().info("Receive HTTP Trigger request: " + request.toString());
        String requestBody = request.getBody();
        if (request.isIsBase64Encoded()) {
            requestBody = new String(java.util.Base64.getDecoder().decode(request.getBody()), StandardCharsets.UTF_8);
        }
        String message = "HTTP Trigger request body: " + requestBody;
        context.getLogger().info(message);
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "text/plain");
        return HTTPTriggerResponse.builder().withStatusCode(200).withHeaders(headers).withBody(request.getBody())
                .withIsBase64Encoded(request.isIsBase64Encoded()).build();
    }
}

この例では、fc-java-coreライブラリに加えて、jacksonライブラリとlombokライブラリを導入する必要があります。 この依存関係は、Maven設定ファイルpom.xmlに追加できます。

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.16.1</version>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.30</version>
</dependency>

あなたが始める前に

上記のサンプルコードを使用して、Javaランタイムで関数を作成し、HTTPトリガーを作成します。 詳細については、「イベント関数の作成」および「HTTPリクエストで関数を呼び出すHTTPトリガーの設定」をご参照ください。

手順

  1. Function Computeコンソールにログインします。 左側のナビゲーションウィンドウで、[関数] をクリックします。

  2. 上部のナビゲーションバーで、リージョンを選択します。 [関数] ページで、管理する関数をクリックします。

  3. 関数の詳細ページで、[トリガー] タブをクリックして、HTTPトリガーのパブリックエンドポイントを取得します。

  4. curlで次のコマンドを実行して、関数を呼び出します。

    curl -i "https://dev-jav-test-fc-luiqas****.cn-shanghai.fcapp.run" -d 'hello fc3.0'

    上記のコマンドでは、https:// dev-jav-test-fc-luiqas **** .cn-shanghai.fcapp.ru nがHTTPトリガーのパブリックエンドポイントです。

    次の応答が返されます。

    HTTP/1.1 200 OK
    Content-Disposition: attachment
    Content-Length: 11
    Content-Type: application/json
    X-Fc-Request-Id: 1-652503f2-afbfd2b1dc4dd0fcb0230959
    Date: Tue, 10 Oct 2023 07:57:38 GMT
    
    hello fc3.0% 
    重要
    • HTTPトリガーの [認証方法] パラメーターが [認証なし] に設定されている場合、Postmanまたはcurlを使用して関数を呼び出すことができます。 詳細については、「手順」をご参照ください。

    • HTTPトリガーの [認証方法] パラメーターが [署名認証] または [JWT認証] に設定されている場合は、署名方法またはJWT認証方法を使用して関数を呼び出します。 詳細については、「」をご参照ください。

考えられるエラー

このサンプルコードは、HTTPトリガーまたはカスタムドメイン名を使用して呼び出すことができます。 API操作を使用しているが、設定されたテストパラメーターがHTTPトリガーの要求形式要件に準拠していない場合、エラーが報告されます。

たとえば、リクエストパラメーターを "Hello, FC!" として設定した後、function Computeコンソールで [Test Function] をクリックして関数を呼び出すと、次のレスポンスが返されます。

{
    "errorType": "com.fasterxml.jackson.databind.exc.MismatchedInputException",
    "errorMessage": "Cannot construct instance of `example.HTTPTriggerEvent` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Hello, FC!')\n at [Source: (byte[])\"\"Hello, FC!\"\"; line: 1, column: 1]",
    "stackTrace": [
        "com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)",
        "com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1588)",
        "com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1213)",
        "com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromString(StdDeserializer.java:311)",
        "com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1495)",
        "com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:207)",
        "com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:197)",
        "com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)",
        "com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)",
        "com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3643)"
    ]
}

サンプルプログラム

Function Computeの公式ライブラリには、さまざまな種類のハンドラーとインターフェイスを使用するサンプルプログラムが含まれています。 各サンプルプログラムには、簡単なコンパイルと展開のためのメソッドが含まれます。 次のアイテムは例を示します。