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
audiences
audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"}
apiKeyRequired
apiKeyRequired = AnnotationBoolean.TRUE
authenticators
{EspAuthenticator.class}
, or you can write your own custom authenticator, as described in Interface Authenticator
.authenticators = {EspAuthenticator.class}
backendRoot
web.xml
file, change the url-pattern
in the EndpointsServlet
section.<url-pattern>/example-api/*</url-pattern>
canonicalName
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:"
nclientIds
clientIds = {"1-web-apps.apps.googleusercontent.com", "2-android-apps.apps.googleusercontent.com"}
defaultVersion
version
attribute.defaultVersion = AnnotationBoolean.TRUE
description
description = "Sample API for a simple game"
documentationLink
documentationLink = "http://link_to/docs"
issuers
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
limitDefinitions = { @ApiLimitMetric(name = "read-requests", displayName = "Read requests", limit = 1000)}
name
name
value: - Must begin with lowercase
- Must
match the regular expression
[a-z]+[A-Za-z0-9]*
name
, the default myapi
is used.name = "foosBall"
namespace
namespace=@ApiNamespace(ownerDomain="your-company.com", ownerName="YourCo", packagePath="cloud/platform"
)root
web.xml
file, change the url-pattern
in the EndpointsServlet
section.<url-pattern>/example-api/*</url-pattern>
scopes
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
title = "My Backend API"
transformers
@ApiTransformer
) that is preferable. This attribute is overridden by @ApiTransformer
.transformers = {BazTransformer.class}
version
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
apiKeyRequired
apiKeyRequired = AnnotationBoolean.TRUE
audiences
@API
. For more information, see Client IDs and audiences
.audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"}
authenticators
{EspAuthenticator.class}
, or you can write your own custom authenticator, as described in Interface Authenticator
authenticators = {EspAuthenticator.class}
clientIds
clientIds = {"1-web-apps.apps.googleusercontent.com", "2-android-apps.apps.googleusercontent.com"}
httpMethod
httpMethod = HttpMethod.GET
issuerAudiences
@Api
.issuerAudiences = { @ApiIssuerAudience(name = "auth0", audiences = {"aud-1.auth0.com", "aud-2.auth0.com"}) }
metricCosts
@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: - name: A name that you specified in the ApiLimitMetric annotation.
- cost: An integer that specifies the cost for each request. The cost allows methods to consume at different rates from the same quota. For example, if a quota has a limit of 1000 and a cost of 1, the calling application can make 1000 requests per minute before going over the limit. With a cost of 2 for the same quota, a calling application can make only 500 requests per minute before going over the limit.
metricCosts = { @ApiMetricCost(name = read-requests", cost = 1) }
name
name
value: - Must begin with lowercase
- Must
match the regular expression
[a-z]+[A-Za-z0-9]*
name
, the default myapi
is used.name = "foosBall.list"
path
path = "foos"
scopes
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
attributesFor readability purposes, the text "per minute per project" is automatically appended to the display name on the Quotaspages.
To maintain consistency with the display names of Google services listed on the Quotaspages that consumers of your API see, we recommend the following for the display name:
- Use "Requests" when you only have one metric.
- When you have multiple metrics, each should describe the type of request and contain the word "requests" (for example "Read requests" or "Write requests").
- Use "quota units" instead of "requests" when any of the costs for this quota is greater than 1.
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"
}