Google App Engine

Endpoint Annotations

Endpoint annotations describe API configuration, methods, parameters, and other vital details that define the properties and behavior of the Endpoint. The annotation that specifies configuration and behavior across the entire API (affecting all the classes exposed in the API and all their exposed methods) is @Api. All public, non-static, non-bridge methods of a class annotated with @Api will be exposed in the public API.

If you need special API configuration for a particular method, you can optionally use @ApiMethod to set configuration on a per method basis. You configure these annotations by setting various attributes, as shown in the tables below.

@Api: API-Scoped Annotations

The annotation @Api is used to configure the whole API, and apply to all public methods of a class unless overridden by @ApiMethod.

(To override a given @Api annotation for a specific class within an API, see @ApiClass and @ApiReference.)

Required Imports

To use this feature, you need the following import:

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

Attributes

@Api Attributes Description Example
audiences Required if your API requires authentication and if you are supporting Android clients.For more information, see Client IDs and Audiences. audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"}
backendRoot The root URL used for method calls to backend instances. If not supplied, the default https://your_app_id.appspot.com/_ah/spi is used. backendRoot = "https://example.appspot.com/_ah/spi"
canonicalName Optional. Used to specify a different or more readable name for the API in the client library. This name is used to generate the names in the client library; the backend API continues to use the value specified in the name property.

For example, if your API has the name set to dfaanalytics, you could use this property to specifiy a canonical name of DFA Group Analytics; the generated client classes would then contain the name DfaGroupAnalytics.

You should include the relevant spaces between the names as shown above; these will be replaced by the appropriate camel casing or underscores.
canonical_name='DFA Analytics'
clientIds Required if your API uses authentication. List of client IDs for clients allowed to request tokens. For more information, see Client IDs and Audiences. clientIds = {"1-web-apps.apps.googleusercontent.com", "2-android-apps.apps.googleusercontent.com"}
defaultVersion Specifies whether a default version is used if none is supplied in the version attribute. defaultVersion = AnnotationBoolean.TRUE
description A short description of the API. This is exposed in the discovery service to describe your API, and may optionally also be used to generate documentation. description = "Sample API for a simple game"
documentationLink Optional. The URL where users can find documentation about this version of the API. This will be surfaced in the API Explorer "Learn More" highlight at the top of the API Explorer page and also in the GPE plugin to allow users to learn about your service. http://link_to/docs
name The name of the API, which is used as the prefix for all of the API's methods and paths. The name value:
  • Must begin with lowercase
  • Must match the regular expression [a-z]+[A-Za-z0-9]*
If you don't specify name, the default myapi is used.
name = "foosBall.list"
namespace Configures namespacing for generated clients. See @ApiNamespace. namespace=@ApiNamespace(ownerDomain="your-company.com",ownerName="YourCo", packagePath="cloud/platform")
root The frontend root URL under which your API methods are exposed for. If not supplied, the default https://your_app_id.appspot.com/_ah/api" is used. root = "https://example.appspot.com/_ah/api"
scopes If not supplied, the default is the email scope (https://www.googleapis.com/auth/userinfo.email), which is required for OAuth. You can override this to specify more OAuth 2.0 scopes if you wish. However, if you do define more than one scope, note that the scope check will pass if the token is minted for any of the specified scopes. To override the scopes specified here for a particular API method, specify different scopes in the @ApiMethod annotation. scopes = {"ss0", "ss1"}
title Optional. The text displayed in API Explorer as the title of your API, and exposed in the discovery and the directory services. title=My Backend API
transformers Specifies a list of custom transformers. Note that there is an alternative annotation (@ApiTransformer) that is preferable. This attribute is overridden by @ApiTransformer. @Api(name = "test", transformers = {BazTransformer.class})
version Specifies your Endpoint’s version. If you don't supply this, the default v1 is used. version = "v2"

Sample @Api Annotation

This annotation is placed above the class definition:

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

@Api(
    version = "v1",
    description = "Sample API",
    scopes = {"ss0", "ss1"},
    audiences = {"aa0", "aa1"},
    clientIds = {"cc0", "cc1"},
    defaultVersion = AnnotationBoolean.TRUE
)

Client IDs and Audiences

In an OAuth2 authentication, an OAuth2 token is issued to a specific client ID, which means that this client ID can be used for restricting access to your APIs. When you register an iOS or Android application in the Google Cloud Console, you create a client ID for it. This client ID is the one requesting an OAuth2 token from Google for authentication purposes. When the backend API is protected by auth, an OAuth2 access token is sent and opened by Google Cloud Endpoints, the client ID is extracted from the token, and then the ID is compared to the backend's declared acceptable Client ID list (the clientIds list).

So, if you want your Endpoints API to authenticate callers, you need to supply a list of clientIds that are allowed to request tokens that can be used with your application. This list should consist of the all client IDs you have obtained through the Google Developers Console for your web, Android, or iOS clients. (This means that the clients must be known at API build-time.) If you specify an empty list, [], then no clients can access the methods protected by Auth.

If you use the clientIds attribute and you want to test authenticated calls to your API using the Google API Explorer, you must supply its client ID in the list of clientIds: the value to use is com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID.

About Audiences

The clientIds list protects the backend API from unauthorized clients. But further protection is needed to protect the clients, so that their auth token will work only for the intended backend API. For Android clients, this mechanism is the audiences attribute, in which you specify the client ID of the backend API.

Note that when you create a Google Cloud Console Project, a default client ID is automatically created and named for use by the project. When you upload your backend API into App Engine, it uses that client ID. This is the web client ID mentioned in the backend API auth docs and the backend tutorial docs.

@ApiMethod: Method-Scoped Annotations

The annotation @ApiMethod is used to supply a different API configuration than the defaults provided by the @Api or @ApiClass annotations. Note that this is optional: all public, non static, non bridge methods in a class with an @Api annotation are exposed in the API, whether they have an @ApiMethod annotation or not.

Attributes within this annotation allow you to configure details of a single API method. If the same attribute is specified in @Api and @ApiMethod, @ApiMethod overrides.

Required Imports

To use this feature, you need the following imports:

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;

Attributes

@ApiMethod Attributes Description Example
name The name for this method in the generated client library. This is automatically prefixed with your API name to create a unique name for the method. The name value:
  • Must begin with lowercase
  • Must match the regular expression [a-z]+[A-Za-z0-9]*
If you don't specify name, the default myapi is used.
name = "foosBall.list"
path The URI path to use to access this method. If you don't set this, a default path is used based on the Java method name. path = "foos"
httpMethod The HTTP method to use. If you don't set this, a default is chosen based on the name of the method. httpMethod = HttpMethod.GET
scopes Specify one or more OAuth 2.0 scopes, one of which is required for calling this method. If you set scopes for a method, it overrides the setting in the @Api annotation. scopes = {"ss0", "ss1"}
audiences Required if your API requires authentication and if you are supporting Android clients.For more information, see Client IDs and Audiences. audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"}
clientIds List of client IDs for clients allowed to request tokens. Required if your API uses authentication. clientIds = {"1-web-apps.apps.googleusercontent.com", "2-android-apps.apps.googleusercontent.com"}

Sample @ApiMethod Annotation

This annotation is placed above the method definition inside a class:

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(
    name = "foos.list",
    path = "foos",
    httpMethod = HttpMethod.GET,
    scopes = {"s0", "s1"},
    audiences = {"a0", "a1"},
    clientIds = {"c0", "c1"}
 )
 public List<Foo> listFoos() {
    return null;
 }

Methods that take an entity as a parameter should use HttpMethod.POST (for insert operations) or HttpMethod.PUT (for update operations):

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

@Named

This annotation indicates the name of the parameter in the request that gets injected here. A parameter that is not annotated with @Named is injected with the whole request object. Important!: There are several commonly used @Named annotations: the one you must use with Endpoints is javax.inject.Named.

Required Imports

To use this feature, you need the following imports:

import javax.inject.Named;

This sample shows the use of @Named:

@ApiMethod(
    name = "foos.remove",
    path = "foos/{id}",
    httpMethod = HttpMethod.DELETE
 )
 public void removeFoo(@Named("id") String id) {
 }

where @Named specifies that only the id parameter is injected in the request.

@ApiNamespace

The @ApiNamespace annotation causes the generated client libraries to have the namespace you specify, rather than a default constructed during client library generation.

By default, if you don't use this annotation, the namespace that is used is the reverse of your-project-id.appspot.com. That is, the package path will be com.appspot.your-project-id.yourApi.

You can change the default namespace by supplying the @ApiNamespace annotation within the @Api annotation:

@Api(
    name = "tictactoe",
    version = "v1",
    namespace=@ApiNamespace(ownerDomain="your-company.com",ownerName="YourCo", packagePath="cloud/platform")
)

with the ownerDomain attribute set to your own company domain and ownerName set to your company name, for example, your-company.com. The reverse of the ownerDomain will then be used for the package path: com.your-company.yourApi.

You can optionally use the packagePath attribute to provide further scoping. For example, by setting packagePath to cloud, the package path used in the client library will be com.your-company.cloud.yourApi. You can add more values to the package path by supplying the delimiter /: packagePath="cloud/platform".

@Nullable

This annotation indicates that a parameter of a method is optional (and therefore a query parameter). @Nullable may only be used with @Named parameters.

@ApiClass

In a multiclass API, used to specify different properties for a given class, overriding equivalent properties in the @Api configuration. See Using @ApiClass for Properties that Can Differ Between Classes for a complete description of this annotation.

@ApiReference

In a multiclass API, used to supply an alternate method of annotation inheritance. See Using @ApiReference Inheritance for a complete description of this annotation.

@ApiResourceProperty

@ApiResourceProperty provides provides more control over how resource properties are exposed in the API. You can use it on a property getter or setter to omit the property from an API resource. You can also use it on the field itself, if the field is private, to expose it in the API. You can also use this annotation to change the name of a property in an API resource.

Required Imports

To use this feature, you need the following imports:

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

Attributes

@ApiResourceProperty Attributes Description Example
ignored If set to AnnotationBoolean.TRUE, omits the property. If not specified or set to AnnotationBoolean.FALSE, the property is not omitted. @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
name If supplied, it specifies the property name to be exposed in the API. @ApiResourceProperty(name = "baz")

Sample Class with @ApiResourceProperty

The following snippet shows a class with property getters annotated with @ApiResourceProperty:

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

@Api(name = "myendpoint")
public class MyEndpoint {
 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();
 }
}

In the code snippet above, @ApiResourceProperty is applied to the getBin getter for the bin property, with the ignored attribute setting telling the Endpoints framework to omit this property in the API resource.

@ApiResourceProperty is also applied to the private field visible, which has no getter or setter. Using this annotation will expose this field as a property in the API resource.

In the same snippet, @ApiResourceProperty is also applied to a different getter, getFoobar, which returns a property value for the foobar property. The name attribute in this annotation tells the Endpoints framework to change the property name in the API resource. The property value itself is unchanged.

In the above example snippet, the JSON representation of a Resp object would look something like this:

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

@ApiTransformer

The @ApiTransformer annotation customizes how a type is exposed in Endpoints through transformation to and from another type. (The transformer specified must be an implementation of com.google.api.server.spi.config.Transformer.)

Using the @ApiTransformer annotation on a class is the preferred way to specify a transformer. However, you could alternatively specify your custom transformer in the transformer attribute of the @Api annotation.

Required imports

To use this feature, you need this import:

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

Sample class with @ApiTransformer

The following snippet shows a class annotated with @ApiTransformer:

import com.google.api.server.spi.config.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;
  }
}

This class will be transformed by the BarTransformer class.

Sample Endpoints transformer class

The following snippet shows a sample transformer class named BarTransformer. This is the transformer referenced by @ApiTransformer in the preceding snippet:

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

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]));
  }
}

Assuming we have an object with a property bar of type Bar, without the above transformer, the object would be represented as:

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

With the transformer, the object is represented as:

{"bar": "1,2"}

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.