Cloud Endpoints Frameworks のアノテーションと構文

Endpoints Frameworks のアノテーションは、API の構成、メソッド、パラメータ、プロパティなど、エンドポイントの動作を定義する重要な詳細を記述します。

Maven プロジェクトを使用してアノテーションを追加する方法については、コードの作成とアノテーションの追加をご覧ください。Maven App Engine の Cloud Endpoints アーティファクトは、バックエンド API を開発してビルドし、そこからクライアント ライブラリを生成するために用意されています。

(API で公開されるすべてのクラスや、そのすべての公開されるメソッドに影響する)API 全体の構成と動作を指定するアノテーションは @Api です。@Api アノテーションが付いたクラスのパブリック、非スタティック、非ブリッジ メソッドはすべて、公開 API で公開されます。

特定のメソッド用に特別な API 構成が必要な場合は、必要に応じて @ApiMethod を使用してメソッドごとの構成を設定できます。次の表に示すように、これらのアノテーションを構成するときにはさまざまな属性を設定します。

@Api: API スコープのアノテーション

アノテーション @Api は API 全体を構成します。また @ApiMethod によってオーバーライドされない限り、このアノテーションはクラスのすべてのパブリック メソッドに適用されます。

API の中で特定のクラスの @Api アノテーションをオーバーライドする方法については、@ApiClass@ApiReference をご覧ください。

必要なインポート

この機能を使用するには、以下をインポートする必要があります。

import com.google.api.server.spi.config.Api;

属性

@Api 属性 説明
audiences API に認証が必要で、Android クライアントをサポートしている場合は必須です。詳細については、クライアント ID とオーディエンスをご覧ください。 audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"}
apiKeyRequired 省略可。API キーを提供するリクエストだけに限定的にアクセスを許可する場合に使用します。 apiKeyRequired = AnnotationBoolean.TRUE
authenticators API が Firebase、Auth0、またはサービス アカウントを使用して認証を行う場合は必須です。API の認証に Google ID トークンを使用する場合、この属性は必要ありません。これは、API レベルでも個々のメソッドのレベルでも設定できます。これを {EspAuthenticator.class} に設定することも、独自の認証システムをプログラミングすることもできます。インターフェース Authenticator の説明をご覧ください。 authenticators = {EspAuthenticator.class}
backendRoot 非推奨。別のパスから API を提供するには、web.xml ファイル内の EndpointsServlet セクションにある url-pattern を変更します。 <url-pattern>/example-api/*</url-pattern>
canonicalName クライアント ライブラリで API に別のわかりやすい名前を付ける場合に使用します。この名前は、クライアント ライブラリで名前を生成するために使用されます。バックエンド API は、name プロパティで指定された値を引き続き使用します。

たとえば、API の namedfaanalytics に設定されている場合、このプロパティを使用して正規名を DFA Group Analytics と指定できます。こうすると、生成されるクライアント クラスに DfaGroupAnalytics という名前が含められます。

名前の間にスペースを入れることをおすすめします。これらは適宜キャメルケースまたはアンダースコアに置き換えられます。
canonicalName = "DFA Analytics:"n
clientIds API で認証を使用する場合は必須。トークンをリクエストすることを許可されたクライアント ID のリスト。詳細については、クライアント ID とオーディエンスをご覧ください。 clientIds = {"1-web-apps.apps.googleusercontent.com", "2-android-apps.apps.googleusercontent.com"}
defaultVersion version 属性に何も指定されない場合にデフォルト バージョンを使用するかどうかを指定します。 defaultVersion = AnnotationBoolean.TRUE
description API の簡単な説明。これは API を説明するために検出サービスで公開され、ドキュメントを生成するために使用することもできます。 description = "Sample API for a simple game"
documentationLink ユーザーがこのバージョンの API に関するドキュメントを参照できる URL。これは、API Explorer ページの上部にある API Explorer の [詳細] リンクに関連付けられており、このリンクをクリックすることで、サービスの詳細を知ることができます。 documentationLink = "http://link_to/docs"
issuers JWT 発行元のカスタムの構成。 issuers = { @ApiIssuer(name = "auth0", issuer = "https://test.auth0.com/authorize", jwksUri = "https://test.auth0.com/.well-known/jwks.json") }
issuerAudiences 個々の発行元のオーディエンス。 issuerAudiences = { @ApiIssuerAudience(name = "auth0", audiences = {"aud-1.auth0.com", "aud-2.auth0.com"}) }
limitDefinitions 省略可。API の割り当てを定義するときに使用されます。詳細については、@ApiLimitMetric をご覧ください。 limitDefinitions = { @ApiLimitMetric(name = "read-requests", displayName = "Read requests", limit = 1000)}
name API のメソッドとパスすべてに使用される接頭辞となる API の名前です。name の値は以下の条件を満たす必要があります。
  • 必ず小文字で始まる必要があります
  • 正規表現 [a-z]+[A-Za-z0-9]* と一致する必要があります
name を指定しない場合、デフォルトの myapi が使用されます。
name = "foosBall"
namespace 生成されたクライアントのために名前空間を設定します。詳細については、@ApiNamespace をご覧ください。 namespace=@ApiNamespace(ownerDomain="your-company.com", ownerName="YourCo", packagePath="cloud/platform")
root 非推奨。別のパスから API を提供するには、web.xml ファイル内の EndpointsServlet セクションにある url-pattern を変更します。 <url-pattern>/example-api/*</url-pattern>
scopes 指定しない場合は、OAuth の使用に必須であるメールのスコープ(https://www.googleapis.com/auth/userinfo.email)がデフォルトとして使用されます。必要に応じてこれをオーバーライドし、より多くの OAuth 2.0 スコープを指定できます。ただし複数のスコープを定義する場合は、指定されたいずれかのスコープ用のトークンが作成されると、スコープ チェックが成功することに注意してください。複数のスコープを要求するには、各スコープをスペースで区切り、1 つの String にして指定します。ここで指定したスコープを特定の API メソッド用にオーバーライドするには、@ApiMethod アノテーション内に別のスコープを指定します。 scopes = {"ss0", "ss1 and_ss2"}
title API のタイトルとして API Explorer に表示されるテキストです。検索や検索サービスにも表示されます。 title = "My Backend API"
transformers transformers のカスタムリストを指定します。優先される代替アノテーション(@ApiTransformer)があるので注意してください。この属性は、@ApiTransformer でオーバーライドされます。 transformers = {BazTransformer.class}
version エンドポイントのバージョンを指定します。バージョンを指定しない場合、デフォルトの v1 が使用されます。 version = "v2"

サンプル @Api アノテーション

このアノテーションはクラス定義の前に配置されています。

/** An endpoint class we are exposing. */
@Api(name = "myApi",
    version = "v1",
    namespace = @ApiNamespace(ownerDomain = "helloworld.example.com",
        ownerName = "helloworld.example.com",
        packagePath = ""))

クライアント ID とオーディエンス

OAuth2 認証では、特定のクライアント ID に対して OAuth2 トークンが発行されます。これにより、クライアント ID を使用して API へのアクセスを制限できます。Google Cloud Console で Android アプリケーションを登録するときは、このためのクライアント ID を作ります。このクライアント ID は認証用に Google に対して OAuth2 トークンをリクエストします。バックエンド API が認証によって保護されている場合、OAuth2 アクセス トークンが送信され、Endpoints によって開かれます。トークンからクライアント ID が抽出され、その ID と、宣言済みの承認されているバックエンド クライアント ID リスト(clientIds リスト)が比較されます。

Endpoints API で呼び出し元を認証する場合は、トークンのリクエストが許可されている clientIds のリストを指定する必要があります。このリストには、Cloud Console から取得した、ウェブ クライアントや Android クライアントのすべてのクライアント ID を含めます。つまり、API の作成時にこれらのクライアントが既知である必要があります。空のリスト {} を指定すると、どのクライアントも、認証によって保護されたメソッドにアクセスできなくなります。

たとえば、clientIds 属性を使用し、Google API Explorer を使用して API への認証済み呼び出しをテストするには、そのクライアント ID を clientIds のリストに指定する必要があります。使用する値は、com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID です。

オーディエンスについて

clientIds リストは、権限のないクライアントからバックエンド API を保護します。ただし、クライアントを保護するには、さらに保護を強化する必要があります。つまり、クライアントの認証トークンが、該当するバックエンド API に関してのみ機能するようにする必要があります。Android クライアントではこのメカニズムは audiences 属性であり、この属性にバックエンド API のクライアント ID を指定します。

Cloud Console プロジェクトを作成するときは、そのプロジェクトで使用するデフォルトのクライアント ID が自動的に作成され、命名されることに注意してください。App Engine にバックエンド API をアップロードするときは、そのクライアント ID が使用されます。これは、API 認証で説明されているウェブ クライアント ID です。

@ApiMethod: Method スコープのアノテーション

アノテーション @ApiMethod は、アノテーション @Api@ApiClass で指定されたデフォルトとは異なる API 構成を指定するために使用します。これは省略可能です。@Api アノテーションが付いたクラスのすべてのパブリック、非スタティック、非ブリッジ メソッドは、@ApiMethod アノテーションの有無に関係なく、API で公開されます。

このアノテーション内の属性を使用すると、単一の API メソッドの詳細を構成できます。@Api@ApiMethod に同じ属性が指定されている場合、@ApiMethod が優先されます。

必要なインポート

この機能を使用するには、以下をインポートする必要があります。

import com.google.api.server.spi.config.AnnotationBoolean;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;

属性

@ApiMethod 属性 説明
apiKeyRequired 省略可。API キーを提供するリクエストだけに限定的にアクセスを許可する場合に使用します。 apiKeyRequired = AnnotationBoolean.TRUE
audiences @API の構成をオーバーライドするには、これを指定します。詳細については、クライアント ID とオーディエンスをご覧ください。 audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"}
authenticators API の認証に Firebase、Auth0、またはサービス アカウントを使用する場合に、この属性を API レベルで設定していなければ必須です。API の認証に Google ID トークンを使用する場合、この属性は必要ありません。これを {EspAuthenticator.class} に設定することも、独自の認証システムをプログラミングすることもできます。インターフェース Authenticator の説明をご覧ください。 authenticators = {EspAuthenticator.class}
clientIds トークンをリクエストすることを許可されたクライアント ID のリスト。API 認証を使用する場合は必須です。 clientIds = {"1-web-apps.apps.googleusercontent.com", "2-android-apps.apps.googleusercontent.com"}
httpMethod 使用する HTTP メソッド。これを設定しない場合、デフォルトでは、メソッド名に基づいて選択されます。 httpMethod = HttpMethod.GET
issuerAudiences @Api の構成をオーバーライドするには、これを指定します。 issuerAudiences = { @ApiIssuerAudience(name = "auth0", audiences = {"aud-1.auth0.com", "aud-2.auth0.com"}) }
metricCosts 省略可。メソッドに割り当て上限があることを指定します。@ApiMetricCost アノテーションを metricCosts に割り当てます。また、limitDefinitions 属性を指定して、@Api アノテーションの割り当てを定義する必要もあります。@ApiMetricCost アノテーションには、次の属性があります。
  • name: ApiLimitMetric アノテーションで指定した名前。
  • cost: 各リクエストのコストを指定する整数値。コストを使用することによって、さまざまなメソッドから同じ割り当てを異なるレートで消費できます。たとえば、割り当ての上限が 1,000 で、コストが 1 の場合、呼び出し元のアプリケーションは、上限内で 1 分間に 1,000 回のリクエストを行えます。同じ割り当てでコストが 2 の場合、呼び出し元のアプリケーションは、1 分間に 500 回のリクエストのみ行えます。
metricCosts = { @ApiMetricCost(name = read-requests", cost = 1) }
name 生成されたクライアント ライブラリに、このメソッドの名前を入力します。自動的にメソッドの名前を作成するためにお使いの API 名が付けられます。name の値は以下の条件を満たす必要があります。
  • 必ず小文字で始まる必要があります
  • 正規表現 [a-z]+[A-Za-z0-9]* と一致する必要があります
name を指定しない場合、デフォルトの myapi が使用されます。
name = "foosBall.list"
path このメソッドのアクセスに使用する URI パス。これを設定しない場合、使用されるデフォルトのパスは Java メソッド名に基づいて決まります。API 管理を追加する予定の場合は、パスの末尾にスラッシュを含めないでください。 path = "foos"
scopes 1 つ以上の OAuth 2.0 スコープを指定します。そのうち 1 つがこのメソッド呼び出しに必要とされます。メソッドの scopes を設定した場合、@Api アノテーションの設定がオーバーライドされます。複数のスコープを定義する場合は、指定されたいずれかのスコープ用のトークンが作成されると、スコープ チェックが成功することに注意してください。複数のスコープを要求するには、各スコープをスペースで区切り、1 つの String にして指定します。 scopes = {"ss0", "ss1 and_ss2"}

サンプル @ApiMethod アノテーション

このアノテーションはクラス内のメソッド定義の前に配置されています。

/** A simple endpoint method that takes a name and says Hi back. */
@ApiMethod(
    name = "sayHiUser",
    httpMethod = ApiMethod.HttpMethod.GET)
public MyBean sayHiUser(@Named("name") String name, User user)
    throws OAuthRequestException, IOException {
  MyBean response = new MyBean();
  response.setData("Hi, " + name + "(" + user.getEmail() + ")");

  return response;
}

エンティティをパラメータとして使用するメソッドは、HttpMethod.POST(挿入オペレーションの場合)または HttpMethod.PUT(更新オペレーションの場合)を使用する必要があります。

@ApiMethod(
    name = "mybean.insert",
    path = "mybean",
    httpMethod = ApiMethod.HttpMethod.POST
)
public void insertFoo(MyBean foo) {
}

@Named

この @Named アノテーションは、サーバー側のメソッドに渡される非エンティティ型のすべてのパラメータで必要です。このアノテーションは、ここに挿入されるリクエスト内のパラメータ名を示します。@Named アノテーションが付いていないパラメータは、リクエスト オブジェクト全体とともに挿入されます。

必要なインポート

この機能を使用するには、以下をインポートする必要があります。

import javax.inject.Named;

このサンプルは、@Named の使用方法を示しています。

/** A simple endpoint method that takes a name and says Hi back. */
@ApiMethod(name = "sayHi")
public MyBean sayHi(@Named("name") String name) {
  MyBean response = new MyBean();
  response.setData("Hi, " + name);

  return response;
}

ただし、@Namedid パラメータのみがリクエストに挿入されることを示しています。

@ApiLimitMetric

このセクションでは、API の割り当てを定義するために必要なアノテーションについて説明します。割り当ての設定に必要なすべての手順については、割り当ての構成をご覧ください。

API スコープのアノテーションlimitDefinitions 属性に @ApiLimitMetric アノテーションを割り当てます。さらに、割り当てを適用するメソッドごとに、@ApiMetricCost@ApiMethod アノテーションに追加する必要があります。

必要なインポート

この機能を使用するには、以下をインポートする必要があります。

import com.google.api.server.spi.config.ApiLimitMetric;

属性

@ApiLimitMetric 属性

説明
name 割り当ての名前。通常、これは割り当てを一意に識別するリクエストのタイプ(「read-requests」または「write-requests」など)です。
displayName Cloud Console の [エンドポイント] > [サービス] ページにある [割り当て] タブに表示される、割り当てを示すテキスト。このテキストは、[IAM と管理] および [API とサービス] の [割り当て] ページで、API ユーザーに対しても表示されます。表示名の最大文字数は 40 文字です。
読みやすくするため、[割り当て] ページで表示名に「プロジェクトあたり毎分」というテキストが自動的に追加されます。
API コンシューマに対して表示される [割り当て] ページにリスト表示される Google サービスの表示名との整合性を保つため、次のような表示名を使用することをおすすめします。
  • 指標(メトリック)が 1 つのみの場合は「requests」を使用します。
  • 指標が複数ある場合は、それぞれにリクエストのタイプを示す単語と「requests」という単語を含めます(「read-requests」または「write-requests」など)。
  • この割り当てに対するコストのいずれかが 1 より大きい場合は、「requests」の代わりに「quota units」を使用します。
limit この割り当てにおける、ユーザー プロジェクトごとの 1 分あたりの最大リクエスト数を示す整数値。

limitDefinitions = {
      @ApiLimitMetric(
        name = "read-requests",
        displayName = "Read requests",
        limit = 1000),
      @ApiLimitMetric(
        name = "write-requests",
        displayName = "Write requests",
        limit = 50),
    }

@ApiNamespace

@ApiNamespace アノテーションを使用すると、クライアント ライブラリ生成中に作成されるデフォルト値ではなく、指定した名前空間を持つクライアント ライブラリが生成されます。

このアノテーションを使用しない場合、デフォルトで使用される名前空間は your-project-id.appspot.com の逆になります。つまり、パッケージパスは com.appspot.your-project-id.yourApi になります。

@ApiNamespace アノテーションを @Api アノテーション内に指定することで、デフォルトの名前空間を変更できます。

/** An endpoint class we are exposing. */
@Api(name = "myApi",
    version = "v1",
    namespace = @ApiNamespace(ownerDomain = "helloworld.example.com",
        ownerName = "helloworld.example.com",
        packagePath = ""))

ownerDomain 属性には会社のドメインを設定し、ownerName には会社名を設定します。たとえば your-company.com と指定すると、ownerDomain を逆にした com.your-company.yourApi がパッケージパスに使用されます。

必要に応じて packagePath 属性を使用すると、スコープをさらに指定できます。たとえば、packagePathcloud に設定すると、クライアント ライブラリで使用されるパッケージパスは com.your-company.cloud.yourApi になります。パッケージパスに複数の値を追加するには、区切り文字 /: packagePath="cloud/platform" を使用します。

@Nullable

このアノテーションは、メソッドのパラメータが省略可能である(したがってクエリ パラメータである)ことを示します。@Nullable は、@Named パラメータを使用する場合にのみ使用できます。

@ApiClass

マルチクラス API では、@ApiClass を使用して特定のクラスに複数の異なるプロパティを指定できます。これにより、@Api 構成の中の同等のプロパティがオーバーライドされます。このアノテーションの詳細については、クラス間で異なるプロパティに対する @ApiClass の使用をご覧ください。

@ApiReference

マルチクラス API では、@ApiReference を使用してアノテーション継承の代替メソッドを指定できます。このアノテーションの詳細については、@ApiReference の継承の使用をご覧ください。

@ApiResourceProperty

@ApiResourceProperty は、API でのリソース プロパティの公開方法を制御します。プロパティのゲッターやセッターでこれを使用すると、API リソースからプロパティを省略できます。また、フィールド自体でこれを使用すると、フィールドがプライベートである場合に API でそれを公開できます。このアノテーションを使用して API リソース内のプロパティの名前を変更することもできます。

必要なインポート

この機能を使用するには、以下をインポートする必要があります。

import com.google.api.server.spi.config.ApiResourceProperty;
import com.google.api.server.spi.config.AnnotationBoolean;

属性

@ApiResourceProperty 属性 説明
ignored AnnotationBoolean.TRUE に設定した場合、プロパティが省略されます。指定されていない場合、または AnnotationBoolean.FALSE に設定している場合、プロパティは省略されません。 @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
name これを指定すると、API で公開されるプロパティ名を指定できます。 @ApiResourceProperty(name = "baz")

@ApiResourceProperty のサンプルクラス

次のスニペットは、@ApiResourceProperty アノテーションが付いたプロパティ ゲッターを持つクラスを示しています。


class Resp {
  private String foobar = "foobar";
  private String bin = "bin";

  @ApiResourceProperty
  private String visible = "nothidden";

  @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
  public String getBin() {
    return bin;
  }

  public void setBin(String bin) {
    this.bin = bin;
  }

  @ApiResourceProperty(name = "baz")
  public String getFoobar() {
    return foobar;
  }

  public void setFoobar(String foobar) {
    this.foobar = foobar;
  }
}

public Resp getResp() {
  return new Resp();
}

前述のコード スニペットでは、bin プロパティの getBin ゲッターに @ApiResourceProperty が適用され、ignored 属性の設定は、API リソース内でこのプロパティを省略するよう Endpoints Frameworks に指示しています。

また、@ApiResourceProperty は、ゲッターやセッターを持たないプライベート フィールド visible にも適用されます。このアノテーションを使用すると、API リソースでプロパティとしてこのフィールドが公開されます。

また、この同じスニペットでは、foobar プロパティのプロパティ値を返す別のゲッター getFoobar にも @ApiResourceProperty を適用しています。このアノテーションの name 属性は、API リソースのプロパティ名を変更するよう Endpoints Frameworks に指示します。プロパティ値自体は変更されません。

前述の例のスニペットでは、Resp オブジェクトの JSON 表現は次のようになります。

{"baz": "foobar", "visible": "nothidden"}

@ApiTransformer

@ApiTransformer アノテーションは、別のタイプとの変換において、Endpoints でタイプがどのように公開されるかをカスタマイズします(指定される変形は、com.google.api.server.spi.config.Transformer の実装である必要があります)。

変形(Transformer)を指定するには、クラスで @ApiTransformer アノテーションを使用することをおすすめします。ただし、独自に作成した変形を @Api アノテーションの transformer 属性で指定することもできます。

必要なインポート

この機能を使用するには、以下をインポートする必要があります。

import com.google.api.server.spi.config.ApiTransformer;

@ApiTransformer のサンプルクラス

次のスニペットは、@ApiTransformer アノテーションが付いたクラスを示しています。


@ApiTransformer(BarTransformer.class)
public class Bar {
  private final int x;
  private final int y;

  public Bar(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public int getX() {
    return x;
  }

  public int getY() {
    return y;
  }
}

このクラスは、BarTransformer クラスによって変形されます。

サンプル Endpoints 変形クラス

次のスニペットは、BarTransformer という名前のサンプル変形クラスを示しています。これは、前のスニペットの @ApiTransformer で参照されている変形です。

public class BarTransformer implements Transformer<Bar, String> {
  public String transformTo(Bar in) {
    return in.getX() + "," + in.getY();
  }

  public Bar transformFrom(String in) {
    String[] xy = in.split(",");
    return new Bar(Integer.parseInt(xy[0]), Integer.parseInt(xy[1]));
  }
}

Bar タイプの bar プロパティを持つオブジェクトがある場合、上記の変形を使用しないと、そのオブジェクトは次のように表されます。

{"bar": {"x": 1, "y": 2}}

変形を使用すると、オブジェクトは次のように表されます。

{"bar": "1,2"}