If a single API is particularly complex, you might want to implement it from
multiple Java classes. To make different classes part of the same API, you
must:

- Give each class the same `name` and `version` strings in their [`@Api` annotation](https://docs.cloud.google.com/endpoints/docs/frameworks/java/annotations.md.txt#api_api-scoped_annotations).
- Add class APIs as a [comma-separated list in `web.xml`](https://docs.cloud.google.com/endpoints/docs/frameworks/java/multiclass.md.txt#update_web_xml).

For example, the following two classes are both part of the
`tictactoe` API:

```java
@Api(name = "tictactoe", version = "v1")
class TicTacToeA { ... }

@Api(name = "tictactoe", version = "v1")
class TicTacToeB { ... }
```

The API configuration is specified through the `@Api` annotation properties.
However, for multiple classes in the same API, the `@Api` requirements extend
beyond simply having the same `name` and `version` strings in the `@Api`
annotation for each class. In fact, your backend API will not work if there
are *any* differences in the API configurations specified in the classes'
`@Api` properties. Any difference in the `@Api` properties for classes in a
multiclass API result in an "ambiguous" API configuration, which will not
work in Cloud Endpoints Frameworks for App Engine.

> [!NOTE]
> **Note:** For a way to specify different properties for classes without using `@Api` properties, see [Using `@ApiClass` for properties that can differ between classes](https://docs.cloud.google.com/endpoints/docs/frameworks/java/multiclass.md.txt#using_apiclass_for_properties_that_can_differ_between_classes).

There are several ways to create a unambiguous multiclass API:

- Manually ensure that all classes in a single API have the exact same `@Api` annotation properties.
- Use annotation inheritance through [Java inheritance](https://docs.cloud.google.com/endpoints/docs/frameworks/java/multiclass.md.txt#using_java_inheritance). In this inheritance, all classes in a single API inherit the same API configuration from a common `@Api`-annotated base class.
- Use annotation inheritance through the [`@ApiReference`](https://docs.cloud.google.com/endpoints/docs/frameworks/java/multiclass.md.txt#using_apireference_inheritance) annotation on all classes in a single API to have them reference the same API configuration from a common `@Api`-annotated class.

## Using `@ApiClass` for properties that can differ between classes

To use this feature, you need the following import:

```java
import com.google.api.server.spi.config.ApiClass;
```

While all properties in the `@Api` annotation must match for all classes in an
API, you can additionally use the `@ApiClass` annotation to provides properties
that don't need to be exactly the same between classes. For example:

```java
// API methods implemented in this class allow only "clientIdA".
@Api(name = "tictactoe", version = "v1")
@ApiClass(clientIds = { "clientIdA" })
class TicTacToeA { ... }

// API methods implemented in this class provide unauthenticated access.
@Api(name = "tictactoe", version = "v1")
class TicTacToeB { ... }
```

where `TicTacToeA` limits access by using a whitelist of client IDs containing
the allowed client ID, and `TicTacToeB` doesn't limit access.

All properties provided by the `@ApiClass` annotation have an equivalent
property in the `@Api` annotation. Note that the `@Api` equivalent property acts
as the API-wide default. If there is an API-wide default for that
same property, specified in `@Api`, the class-specific `@ApiClass` property
overrides the API-wide default.

The following examples illustrate the overriding of `@Api` properties by the
class-specific `@ApiClass` equivalents:

```java
// For this class "boards" overrides "games".
@Api(name = "tictactoe", version = "v1", resource = "games")
@ApiClass(resource = "boards")
class TicTacToeBoards { ... }

// For this class "scores" overrides "games".
@Api(name = "tictactoe", version = "v1", resource = "games")
@ApiClass(resource = "scores")
class TicTacToeScores { ... }

// For this class, the API-wide default "games" is used as the resource.
@Api(name = "tictactoe", version = "v1", resource = "games")
class TicTacToeGames { ... }
```

## Annotation inheritance

The `@Api` and `@ApiClass` annotation properties can be inherited from from
other classes, and individual properties can be overridden either through
[Java inheritance](https://docs.cloud.google.com/endpoints/docs/frameworks/java/multiclass.md.txt#using_java_inheritance)
or
[`@ApiReference` inheritance](https://docs.cloud.google.com/endpoints/docs/frameworks/java/multiclass.md.txt#using_apireference_inheritance)

### Using Java inheritance

A class that extends another class with `@Api` or `@ApiClass` annotations
behaves as if annotated with the same properties. For example:

```java
@Api(name = "tictactoe", version = "v1")
class TicTacToeBase { ... }

// TicTacToeA and TicTacToeB both behave as if they have the same @Api annotation as
// TicTacToeBase
class TicTacToeA extends TicTacToeBase { ... }
class TicTacToeB extends TicTacToeBase { ... }
```

Annotations are only inherited through Java subclassing, not through interface
implementation. For example:

```java
@Api(name = "tictactoe", version = "v1")
interface TicTacToeBase { ... }
// Does *not* behave as if annotated.
class TicTacToeA implements TicTacToeBase { ... }
```

As a result, *there is no support for any sort of multiple inheritance* of
frameworks annotations.

Inheritance works for `@ApiClass` too:

```java
@ApiClass(resource = "boards")
class BoardsBase { ... }

// TicTacToeBoards behaves as if annotated with the @ApiClass from BoardsBase.
// Thus, the "resource" property will be "boards".
@Api(name = "tictactoe", version = "v1", resource = "scores")
class TicTacToeBoards extends BoardsBase { ... }
```

where `TicTacToeBoards` inherits the `resource` property value `boards` from
`BoardsBase`, thus overriding the `resource` property setting (`scores`) in its
`@Api` annotation. Remember that if any class has specified the resource
property in the `@Api` annotation, all of the classes need to specify that same
setting in the `@Api` annotation; this inheritance technique lets you override
that `@Api` property.

### Using `@ApiReference` inheritance

To use this feature, you need the following import:

```java
import com.google.api.server.spi.config.ApiReference;
```

The `@ApiReference` annotation provides an alternate way to specify annotation
inheritance. A class that uses `@ApiReference` to specify another class with
`@Api` or `@ApiClass` annotations behaves as if annotated with the same
properties. For example:

```java
@Api(name = "tictactoe", version = "v1")
class TicTacToeBase { ... }

// TicTacToeA behaves as if it has the same @Api annotation as TicTacToeBase
@ApiReference(TicTacToeBase.class)
class TicTacToeA { ... }
```

If both Java inheritance and the `@ApiReference` are used, the annotations
inherit through the `@ApiReference` annotation only. `@Api` and `@ApiClass`
annotations on the class inherited through Java inheritance are ignored. For
example:

```java
@Api(name = "tictactoe", version = "v1")
class TicTacToeBaseA { ... }
@Api(name = "tictactoe", version = "v2")
class TicTacToeBaseB { ... }

// TicTacToe will behave as if annotated the same as TicTacToeBaseA, not TicTacToeBaseB.
// The value of the "version" property will be "v1".
@ApiReference(TicTacToeBaseA.class)
class TicTacToe extends TicTacToeBaseB { ... }
```

### Overriding inherited configuration

Whether inheriting configuration by using Java inheritance or `@ApiReference`,
you can override the inherited configuration by using a new `@Api` or
`@ApiClass` annotation. Only configuration properties specified in the new
annotation are overridden. Properties that are unspecified are still inherited.
For example:

```java
@Api(name = "tictactoe", version = "v2")
class TicTacToe { ... }

// Checkers will behave as if annotated with name = "checkers" and version = "v2"
@Api(name = "checkers")
class Checkers extends TicTacToe { ... }
```

Overriding inheritance works for `@ApiClass` too:

```java
@Api(name = "tictactoe", version = "v1")
@ApiClass(resource = "boards", clientIds = { "c1" })
class Boards { ... }

// Scores will behave as if annotated with resource = "scores" and clientIds = { "c1" }
@ApiClass(resource = "scores")
class Scores { ... }
```

Overriding also works when inheriting through `@ApiReference`:

```java
@Api(name = "tictactoe", version = "v2")
class TicTacToe { ... }

// Checkers will behave as if annotated with name = "checkers" and version = "v2"
@ApiReference(TicTacToe.class)
@Api(name = "checkers")
class Checkers { ... }
```

### Inheriting `@ApiMethod` annotations

The `@ApiMethod` annotation can be inherited from overridden methods. For
example:

```java
class TicTacToeBase {
  @ApiMethod(httpMethod = "POST")
  public Game setGame(Game game) { ... }
}
@Api(name = "tictactoe", version = "v1")
class TicTacToe extends TicTacToeBase {
  // setGame behaves as if annotated with the @ApiMethod from TicTacToeBase.setGame.
  // Thus the "httpMethod" property will be "POST".
  @Override
  public Game setGame(Game game) { ... }
}
```

Similarly to `@Api` and `@ApiClass` annotation inheritance, if multiple methods
overriding each other have `@ApiMethod` annotations, individual properties can
be overridden. For example:

```java
class TicTacToeBase {
  @ApiMethod(httpMethod = "POST", clientIds = { "c1" })
  public Game setGame(Game game) { ... }
}
@Api(name = "tictactoe", version = "v1")
class TicTacToe extends TicTacToeBase {
  // setGame behaves as if annotated with httpMethod = "GET" and clientIds = { "c1"}.
  @ApiMethod(httpMethod = "GET")
  @Override
  public Game setGame(Game game) { ... }
}
```

There is no `@ApiReference` annotation or equivalent for methods, so
`@ApiMethod` is always inherited through Java inheritance, not through
`@ApiReference`.

## Inheritance and precedence rules

To synopsize the preceding discussion, the follow table shows the inheritance
rules and order of precedence.

| Annotation/inheritance | Rule |
|---|---|
| `@Api` | Must be identical for all classes. |
| `@ApiClass` | Specified for a class to override `@Api` properties. |
| Java inheritance | Class inherits `@Api` and `@ApiClass` of base class. |
| `@ApiReference` | Class inherits `@Api` and `@ApiClass` of referenced class. |
| Using `@ApiReference` on a class (Java) inheriting from a base class | Class inherits the `@Api` and `@ApiClass` of referenced class, *not* from the base class. |

## Common use cases for annotation inheritance

The following are examples of the typical use cases for inheritance:

For API versioning:

```java
@Api(name = "tictactoe", version = "v1")
class TicTacToeV1 { ... }
@Api(version = "v2")
class TicTacToeV2 extends TicTacToeV1 { ... }
```

For multiclass APIs:

```java
@Api(name = "tictactoe", version = "v1")
class TicTacToeBase {}
@ApiClass(resource = "boards")
class TicTacToeBoards extends TicTacToeBase { ... }
@ApiClass(resource = "scores")
class TicTacToeScores extends TicTacToeBase { ... }
```

For testing different versions of the same API:

```java
@Api(name = "tictactoe", version = "v1")
class TicTacToe {
  protected Foo someMethod() {
    // Do something real;
  }

  public Foo getFoo() { ... }
}


@Api(version="v1test")
class TicTacToeTest extends TicTacToe {
  protected Foo someMethod() {
    // Stub out real action;
  }
}
```

where `someMethod` might return pre-determined responses, avoid calls with
side-effects, skip a network or datastore request, and so forth.

## Adding the classes to `web.xml`

After annotating your classes, you must add them to your `web.xml` file. The
following example shows a single class:

```xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!-- Wrap the backend with Endpoints Frameworks v2. -->
    <servlet>
        <servlet-name>EndpointsServlet</servlet-name>
        <servlet-class>com.google.api.server.spi.EndpointsServlet</servlet-class>
        <init-param>
            <param-name>services</param-name>
            <param-value>com.example.skeleton.MyApi</param-value>
        </init-param>
    </servlet>
    <!-- Route API method requests to the backend. -->
    <servlet-mapping>
        <servlet-name>EndpointsServlet</servlet-name>
        <url-pattern>/_ah/api/*</url-pattern>
    </servlet-mapping>
</web-app>
```

To add multiple classes:

1. Replace `<param-value>com.example.skeleton.MyApi</param-value>` with your
   own API class name.

2. Add each class inside this same `<param-value>` field separated by a comma,
   for example:

   ```java
   <param-value>com.example-company.example-api.Hello,com.example-company.example-api.Goodbye</param-value>
   ```