The Endpoints Frameworks annotations describe API configuration, methods, parameters, and other vital details that define the properties and behavior of the endpoint.
See Writing and annotating code for information on adding annotations by using a Maven project. Maven App Engine Cloud Endpoints artifacts are provided to create and build a backend API, and generate a client library from it.
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
are
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
following tables.
@Api
: API-scoped annotations
The annotation
@Api
configures the whole API, and applies 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"} |
apiKeyRequired |
Optional. Used to restrict access to requests that supply an API key. | apiKeyRequired = AnnotationBoolean.TRUE |
authenticators |
Required if your API authenticates using Firebase, Auth0, or service accounts. This attribute isn't required if your API authenticates using Google ID tokens. You can set this at the API level or at the individual method level. Set it to {EspAuthenticator.class} , or you can write your own custom authenticator, as described in Interface Authenticator. |
authenticators = {EspAuthenticator.class} |
backendRoot |
Deprecated. To serve your API from a different path, in your web.xml file, change the url-pattern in the EndpointsServlet section. |
<url-pattern>/example-api/*</url-pattern> |
canonicalName |
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 specify 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; these are replaced by the appropriate camel casing or underscores. |
canonicalName = "DFA Analytics:" n |
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 |
The URL where users can find documentation about this version of the API. This is surfaced in the API Explorer "Learn More" highlight at the top of the API Explorer page to allow users to learn about your service. | documentationLink = "http://link_to/docs" |
issuers |
The custom JWT issuer configurations. | issuers = { @ApiIssuer(name = "auth0", issuer = "https://test.auth0.com/authorize", jwksUri = "https://test.auth0.com/.well-known/jwks.json") } |
issuerAudiences |
Audiences for individual issuers. | issuerAudiences = { @ApiIssuerAudience(name = "auth0", audiences = {"aud-1.auth0.com", "aud-2.auth0.com"}) } |
limitDefinitions |
Optional. Used to define quotas for your API. See @ApiLimitMetric . |
limitDefinitions = { @ApiLimitMetric(name = "read-requests", displayName = "Read requests", limit = 1000)} |
name |
The name of the API, which is used as the prefix for all of the API's methods and paths. The name value:
name , the default myapi is used. |
name = "foosBall" |
namespace |
Configures namespacing for generated clients. See @ApiNamespace . |
namespace=@ApiNamespace(ownerDomain="your-company.com", ownerName="YourCo", packagePath="cloud/platform" ) |
root |
Deprecated. To serve your API from a different path, in your web.xml file, change the url-pattern in the EndpointsServlet section. |
<url-pattern>/example-api/*</url-pattern> |
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 passes if the token is minted for any of the specified scopes. To require multiple scopes, a single String should be specified with a space between each scope. To override the scopes specified here for a particular API method, specify different scopes in the @ApiMethod annotation. |
scopes = {"ss0", "ss1 and_ss2"} |
title |
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 . |
transformers = {BazTransformer.class} |
version |
Specifies your version of endpoint. If you don't supply this, the default v1 is used. |
version = "v2" |
Sample@Api
annotation
This annotation is placed before the class definition:
Client IDs and audiences
For OAuth2 authentication, an OAuth2 token is issued to a specific client ID,
which means that you can use the client ID to restrict access to your APIs.
When you register an 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 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).
If you want your Endpoints API to authenticate callers, you need
to supply a list of clientIds
that are allowed to request tokens. This list
should consist of the all client IDs you have obtained through the
Google Cloud console
for your web or Android 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
only works 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 API authentication.
@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, and 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 |
---|---|---|
apiKeyRequired |
Optional. Used to restrict access to requests that supply an Api key. | apiKeyRequired = AnnotationBoolean.TRUE |
audiences |
Supply this if you wish to override the configuration in @API . For more information, see Client IDs and audiences. |
audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"} |
authenticators |
Required if your API authenticates by using Firebase, Auth0, or service accounts, and you haven't set this attribute at the API level. This attribute isn't required if your API authenticates using Google ID tokens. Set it to {EspAuthenticator.class} , or you can write your own custom authenticator, as described in Interface Authenticator |
authenticators = {EspAuthenticator.class} |
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"} |
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 |
issuerAudiences |
Supply this if you wish to override the configuration in @Api . |
issuerAudiences = { @ApiIssuerAudience(name = "auth0", audiences = {"aud-1.auth0.com", "aud-2.auth0.com"}) } |
metricCosts |
Optional. Indicates that the method has a quota limit. You assign the @ApiMetricCost annotation to metricCosts . You must also specify the limitDefinitions attribute to define the quota in the @Api annotation. The @ApiMetricCost annotation takes the following attributes:
|
metricCosts = { @ApiMetricCost(name = read-requests", cost = 1) } |
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:
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. If you plan to add API management, don't include a trailing slash in the path. | path = "foos" |
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. If you do define more than one scope, note that the scope check passes if the token is minted for any of the specified scopes. To require multiple scopes, specify a single String with a space between each scope. |
scopes = {"ss0", "ss1 and_ss2"} |
Sample @ApiMethod
annotation
This annotation is placed before the method definition inside a class:
Methods that take an entity as a parameter should use HttpMethod.POST
(for insert operations) or HttpMethod.PUT
(for update operations):
@Named
The @Named
annotation is required for all non-entity type parameters passed to
server-side methods. This annotation indicates the name of the parameter in the
request that gets injected here. A parameter that isn't annotated with @Named
is injected with the whole request object.
Required imports
To use this feature, you need the following imports:
import javax.inject.Named;
This sample shows the use of @Named
:
where @Named
specifies that only the id
parameter is injected
in the request.
@ApiLimitMetric
This section describes the annotations required to define quotas for your API. See Configuring quotas for all the steps required to setup a quota.
You assign the @ApiLimitMetric
annotation to the limitDefinitions
attribute of the
API-scoped annotations.
You must also add @ApiMetricCost
to the
@ApiMethod
annotations
for each method that you want to apply a quota to.
Required imports
To use this feature, you need the following import:
import com.google.api.server.spi.config.ApiLimitMetric;
Attributes
@ApiLimitMetric attributes
|
Description |
---|---|
name | The name for the quota. Typically, this is the type of request (for example, "read-requests" or "write-requests") that uniquely identifies the quota |
displayName | The text displayed to identify the quota on the Quotas tab
on Endpoints > Services page of the Google Cloud console. This
text is also
displayed to consumers of your API on the Quotas page of
IAM & admin and API & services. The display name must be a maximum of 40
characters. For readability purposes, the text "per minute per project" is automatically appended to the display name on the Quotas pages. To maintain consistency with the display names of Google services listed on the Quotas pages that consumers of your API see, we recommend the following for the display name:
|
limit | An integer value that is the maximum number of requests per minute per consumer project for the quota. |
Example
limitDefinitions = {
@ApiLimitMetric(
name = "read-requests",
displayName = "Read requests",
limit = 1000),
@ApiLimitMetric(
name = "write-requests",
displayName = "Write requests",
limit = 50),
}
@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 is
com.appspot.your-project-id.yourApi
.
You can change the default namespace by supplying the @ApiNamespace
annotation
within the @Api
annotation:
Set the ownerDomain
attribute to your own company domain and ownerName
to your company name, for example, your-company.com
. The reverse of the
ownerDomain
is 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 is 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,
you can use @ApiClass
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,
you can use @ApiReference
to
supply an alternate method of annotation inheritance. See
Using @ApiReference
inheritance
for a complete description of this annotation.
@ApiResourceProperty
@ApiResourceProperty
provides 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
:
In the preceding code snippet, @ApiResourceProperty
is applied
to the getBin
getter for the bin
property, with the ignored
attribute
setting telling Endpoints Frameworks 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 exposes 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 Endpoints Frameworks to change the property name in
the API resource. The property value itself is unchanged.
In the preceding example snippet, the JSON representation of a Resp
object
looks similar to 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 can alternatively specify your custom
transformer in the transformer
attribute of the
@Api
annotation.
Required imports
To use this feature, you need the following import:
import com.google.api.server.spi.config.ApiTransformer;
Sample class with @ApiTransformer
The following snippet shows a class annotated with @ApiTransformer
:
This class is 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:
Assuming there is an object with a property bar
of type Bar
, without the
preceding transformer, the object is represented as:
{"bar": {"x": 1, "y": 2}}
With the transformer, the object is represented as:
{"bar": "1,2"}