Wenn eine einzelne API besonders komplex ist, wollen Sie sie möglicherweise von mehreren Java-Klassen implementieren. Um derselben API verschiedene Klassen zuzuordnen, müssen Sie
- Legen Sie für jede Klasse die gleichen Strings für
name
undversion
in der Annotation@Api
fest. - Fügen Sie Klassen-APIs als durch Kommas getrennte Liste in
web.xml
ein.
Die folgenden beiden Klassen sind z. B. Teil der tictactoe
API:
@Api(name = "tictactoe", version = "v1")
class TicTacToeA { … }
@Api(name = "tictactoe", version = "v1")
class TicTacToeB { … }
Die API-Konfiguration wird durch die Attribute in der Annotation @Api
festgelegt.
Die Anforderungen @Api
für mehrere Klassen in der gleichen API sind allerdings nicht schon durch die gleichen Strings für name
und version
in der Annotation @Api
erfüllt. Die Back-End API funktioniert nicht, wenn in den API-Konfigurationen, die in den Attributen @Api
der Klasse festgelegt sind, irgendwelche Abweichungen vorliegen. Jeder Unterschied in den @Api
-Attributen von Klassen in einer API mit mehreren Klassen führt zu einer nicht eindeutigen API-Konfiguration, die in Cloud Endpoints Frameworks für App Engine nicht funktioniert.
Eine eindeutige mehrklassige API kann auf mehrere Arten erstellt werden:
- Stellen Sie manuell sicher, dass alle Klassen einer einzelnen API die exakt gleichen Attribute in der Annotation
@Api
haben. - Verwenden Sie die Übernahme der Annotation durch Java-Übernahme.
Bei dieser Übernahme übernehmen alle Klassen in einer einzelnen API die gleiche API-Konfiguration von einer gemeinsamen
@Api
-annotierten Standardklasse. - Verwenden Sie die Übernahme der Annotation mithilfe der
@ApiReference
-Annotation für alle Klassen in einer einzelnen API, sodass sie dieselbe API-Konfiguration von einer gemeinsamen@Api
-annotierten Klasse beziehen.
@ApiClass
für abweichende Attribute in Klassen verwenden
Für diese Funktion ist der folgende Import erforderlich:
import com.google.api.server.spi.config.ApiClass;
Obwohl alle Attribute in der Annotation @Api
für alle Klassen in der API übereinstimmen müssen, können Sie zusätzlich mit der Annotation @ApiClass
Attribute bereitstellen, die nicht zwingend übereinstimmen müssen. Beispiel:
// 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 { … }
Dabei beschränkt TicTacToeA
den Zugriff mithilfe einer weißen Liste mit Client-IDs mit der zulässigen Client-ID. TicTacToeB
beschränkt den Zugriff nicht.
Alle von der Annotation @ApiClass
zur Verfügung gestellten Attribute haben ein äquivalentes Attribut in der Annotation @Api
. Beachten Sie, dass das @Api
-äquivalente Attribut als API-weiter Standard gilt. Wenn es einen API-weiten Standard für dasselbe in @Api
angegebene Attribut gibt, überschreibt das klassenspezifische Attribut @ApiClass
den API-weiten Standard.
Das folgende Beispiel zeigt, wie die klassenspezifischen @ApiClass
-Äquivalente die @Api
-Attribute überschreiben:
// 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 { … }
Annotationsübernahme
Die Annotationsattribute @Api
und @ApiClass
können von anderen Klassen übernommen und einzelne Attribute durch Java-Übernahme oder @ApiReference
-Übernahme überschrieben werden.
Java-Übernahme verwenden
Eine Klasse, die eine andere Klasse mit @Api
- oder @ApiClass
-Annotationen erweitert, verhält sich so, als ob sie mit denselben Attributen annotiert wäre. Beispiel:
@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 { … }
Annotationen werden nur durch Java-Subklassen übernommen, nicht durch Schnittstellenimplementierung. Beispiel:
@Api(name = "tictactoe", version = "v1")
interface TicTacToeBase { … }
// Does *not* behave as if annotated.
class TicTacToeA implements TicTacToeBase { … }
Daraus folgt, dass es keine Unterstützung für jegliche Form der mehrfachen Übernahme von Frameworks-Annotationen gibt.
Die Übernahme funktioniert auch für @ApiClass
:
@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 { … }
Dabei übernimmt TicTacToeBoards
den resource
-Attributwert boards
von BoardsBase
und überschreibt damit die resource
-Attributeinstellung (scores
) in der Annotation @Api
. Denken Sie daran, dass alle Klassen die gleiche Einstellung in der Annotation @Api
angeben müssen, falls eine Klasse das Ressourcenattribut in der Annotation @Api
angegeben hat. Mit dieser Methode der Übernahme können Sie das Attribut @Api
überschreiben.
@ApiReference
-Übernahme verwenden
Für diese Funktion ist der folgende Import erforderlich:
import com.google.api.server.spi.config.ApiReference;
Die Annotation @ApiReference
bietet eine Alternative, um die Übernahme der Annotation anzugeben. Eine Klasse, die @ApiReference
verwendet, um eine andere Klasse mit @Api
- oder @ApiClass
-Annotationen anzugeben, verhält sich so, als ob sie mit denselben Attributen annotiert wäre. Beispiel:
@Api(name = "tictactoe", version = "v1")
class TicTacToeBase { … }
// TicTacToeA behaves as if it has the same @Api annotation as TicTacToeBase
@ApiReference(TicTacToeBase.class)
class TicTacToeA { … }
Wenn sowohl die Java-Übernahme als auch @ApiReference
verwendet werden, erfolgt die Übernahme nur durch die Annotation @ApiReference
. @Api
- und @ApiClass
-Annotationen für die durch Java-Übernahme übernommene Klasse werden ignoriert. Beispiel:
@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 { … }
Übernommene Konfiguration überschreiben
Unabhängig davon, ob Sie die Konfiguration mithilfe von Java-Übernahme oder @ApiReference
übernehmen, können Sie die übernommene Konfiguration mit einer neuen @Api
- oder @ApiClass
-Annotation überschreiben. Nur in der neuen Annotation angegebene Konfigurationsattribute werden überschrieben. Attribute, die nicht angegeben sind, werden trotzdem übernommen.
Beispiel:
@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 { … }
Das Überschreiben von Übernahmen funktioniert auch für @ApiClass
:
@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 { … }
Das Überschreiben funktioniert auch für Übernahmen mithilfe von @ApiReference
:
@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 { … }
@ApiMethod
-Annotationen übernehmen
Die Annotation @ApiMethod
kann von überschriebenen Methoden übernommen werden. Beispiel:
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) { … }
}
Ähnlich wie bei der Übernahme von @Api
- und @ApiClass
-Annotationen können einzelne Attribute überschrieben werden, wenn mehrere sich überschreibende Methoden @ApiMethod
-Annotationen haben. Beispiel:
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) { … }
}
Es gibt keine @ApiReference
-Annotation oder -Äquivalent für Methoden, also wird @ApiMethod
immer durch Java-Übernahme übernommen, nicht durch @ApiReference
.
Übernahme- und Vorrangregeln
Zur Zusammenfassung der obigen Diskussion zeigt die folgende Tabelle die Übernahmeregeln und die Reihenfolge des Vorrangs.
Annotation/Übernahme | Regel |
---|---|
@Api |
Muss für alle Klassen gleich sein. |
@ApiClass |
Angegeben für eine Klasse, um @Api -Attribute zu überschreiben. |
Java-Übernahme | Die Klasse übernimmt @Api und @ApiClass der Standardklasse. |
@ApiReference |
Die Klasse übernimmt @Api und @ApiClass der Referenzklasse. |
@ApiReference auf eine Klasse (Java) anwenden, die von einer Standardklasse übernimmt. |
Klasse übernimmt @Api und @ApiClass der Referenzklasse, nicht der Standardklasse. |
Häufige Anwendungsfälle für die Annotationsübernahme
Die folgenden Beispiele zeigen typische Anwendungsfälle für die Übernahme:
Für API-Versionierung:
@Api(name = "tictactoe", version = "v1")
class TicTacToeV1 { … }
@Api(version = "v2")
class TicTacToeV2 extends TicTacToeV1 { … }
Für APIs mit mehreren Klassen:
@Api(name = "tictactoe", version = "v1")
class TicTacToeBase {}
@ApiClass(resource = "boards")
class TicTacToeBoards extends TicTacToeBase { … }
@ApiClass(resource = "scores")
class TicTacToeScores extends TicTacToeBase { … }
Zum Testen verschiedener Versionen der gleichen API:
@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;
}
}
Dabei gibt someMethod
möglicherweise die vorgegebenen Antworten zurück, verhinderte Aufrufe mit Nebenwirkungen, überspringt eine Netzwerk- oder Datastore-Anfrage usw.
Klassen zu web.xml
hinzufügen
Nachdem die Klassen annotiert wurden, müssen sie der Datei web.xml
hinzugefügt werden. Das folgende Beispiel enthält eine einzelne Klasse:
So fügen Sie mehrere Klassen hinzu:
Ersetzen Sie
<param-value>com.example.skeleton.MyApi</param-value>
durch den API-Klassennamen.Fügen Sie jede Klasse jeweils durch ein Komma getrennt innerhalb dieses
<param-value>
-Felds ein. Beispiel:<param-value>com.example-company.example-api.Hello,com.example-company.example-api.Goodbye</param-value>