迁移到适用于 App Engine 的 Cloud Endpoints Frameworks 2.0 版

本页面介绍如何将现有 Cloud Endpoints 1.0 版应用迁移到 Java 版适用于 App Engine 的 Endpoints Frameworks

优点

新版框架具有诸多优势,具体如下所示:

  • 缩短了请求延迟时间。
  • 可更好地与 App Engine 功能(例如自定义网域)集成。
  • 提供对 Guice 配置的官方支持。
  • 提供多种新的 API 管理功能供您选择。

Endpoints Frameworks 2.0 版不会影响 API 的接口。迁移后,现有客户端仍可继续运行,无需更改任何客户端代码。

目前不包含的功能和工具

目前不支持以下功能。如果您需要使用其中任何功能,请提交功能请求

  • JSON-RPC 协议,这是旧版 iOS 客户端所需的功能。要为您的 Endpoints Frameworks 2.0 版 API 创建 iOS 客户端,我们建议您使用适用于 REST API 的 Google API Objective-C 客户端库
  • 自动 ETag
  • 自动 kind 字段
  • IDE 集成
  • fields 部分响应
  • 自动创建 PATCH API 方法

此外,Android Studio 对 Endpoints 1.0 版的支持不适用于 2.0 版。

使用发现文档迁移到 Endpoints Frameworks 2.0 版

Endpoints Frameworks 2.0 版已改用 com.google.endpoints 组中的 Maven 工件。所需的基本 JAR 位于 endpoints-framework 工件中。如果您希望使用 Guice 配置,请添加 endpoints-framework-guice 工件。

以下说明介绍了如何使用发现文档从 Endpoints Frameworks 1.0 版迁移到 Endpoints Frameworks 2.0 版:

  1. 下载并初始化 Cloud SDK
  2. 运行以下命令:
    1. 确保 Cloud SDK 有权访问您在 GCP 上的数据和服务:
      gcloud auth login
    2. 使用应用默认凭据:
      gcloud auth application-default login
    3. 安装 Cloud SDK app-engine-java 组件:
      gcloud components install app-engine-java
    4. 更新为 Cloud SDK 和所有组件的最新版本:
      gcloud components update
  3. 使用 Maven 或 Gradle 迁移:
  4. Maven

    1. 移除旧版依赖项,即 appengine-endpoints 工件:
      <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-endpoints</artifactId>
            <version>1.9.53</version>
      </dependency>
    2. 添加新版 Endpoints Frameworks 依赖项:
      <dependency>
          <groupId>com.google.endpoints</groupId>
          <artifactId>endpoints-framework</artifactId>
          <version>2.2.1</version>
      </dependency>
    3. 添加新版 Endpoints Frameworks 插件,并为生成的发现文档定义主机名:
      <plugin>
          <groupId>com.google.cloud.tools</groupId>
          <artifactId>endpoints-framework-maven-plugin</artifactId>
          <version>1.0.2</version>
          <configuration>
              <!-- plugin configuration -->
              <hostname>YOUR-PROJECT-ID.appspot.com</hostname>
          </configuration>
      </plugin>
    4. 添加新版 App Engine Maven 插件:
      <plugin>
          <groupId>com.google.cloud.tools</groupId>
          <artifactId>appengine-maven-plugin</artifactId>
          <version>1.3.2</version>
          <configuration>
              <!-- deploy configuration -->
          </configuration>
      </plugin>
    5. 更新项目 web.xml 文件中的 API 入口点:
      • 将出现的所有 SystemServiceServlet 重命名为 EndpointsServlet
      • 将出现的所有路径 /_ah/spi/ 替换为所需的新路径 /_ah/api/

        以下代码标签页显示迁移前后 web.xml 的内容:

        迁移前

        Endpoints Frameworks 1.0 版 web.xml

        <servlet>
            <servlet-name>SystemServiceServlet</servlet-name>
            <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
            <init-param>
                <param-name>services</param-name>
                <param-value>com.example.helloendpoints.Greetings</param-value>
            </init-param>
            <init-param>
                <param-name>restricted</param-name>
                <param-value>false</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>SystemServiceServlet</servlet-name>
            <url-pattern>/_ah/spi/*</url-pattern>
        </servlet-mapping>

        迁移后

        Endpoints Frameworks 2.0 版 web.xml

        <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.helloendpoints.Greetings</param-value>
            </init-param>
            <init-param>
                <param-name>restricted</param-name>
                <param-value>false</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>EndpointsServlet</servlet-name>
            <url-pattern>/_ah/api/*</url-pattern>
        </servlet-mapping>

    6. 修改依赖项后,清理项目:
      mvn clean
    7. 您可以生成发现文档:
      mvn endpoints-framework:discoveryDocs
      详细了解 Maven Endpoints Frameworks 插件目标
    8. 您可以部署项目:
      mvn appengine:deploy

      详细了解 Maven App Engine 插件目标

    Gradle

    1. 移除旧版依赖项,即 appengine-endpoints 工件:
      compile group: 'com.google.appengine', name: 'appengine-endpoints', version: '+'
    2. 添加新版 Endpoints Frameworks 依赖项:
      compile group: 'com.google.endpoints', name: 'endpoints-framework', version: '2.0.8'
    3. 添加新版 App Engine 和 Endpoints Frameworks 插件:
      buildscript {    // Configuration for building
        repositories {
          mavenCentral()
          jcenter()    // Bintray's repository - a fast Maven Central mirror & more
        }
        dependencies {
          // App Engine Gradle plugin
          classpath 'com.google.cloud.tools:appengine-gradle-plugin:1.3.3'
      
          // Endpoints Frameworks Gradle plugin
          classpath 'com.google.cloud.tools:endpoints-framework-gradle-plugin:1.0.2'
        }
      }
    4. 应用新版 App Engine 和 Endpoints Frameworks 插件:
      apply plugin: 'com.google.cloud.tools.appengine'
      apply plugin: 'com.google.cloud.tools.endpoints-framework-server'
    5. 为生成的发现文档定义主机名端点:
      endpointsServer {
        // Endpoints Framework Plugin server-side configuration
        hostname = "YOUR-PROJECT-ID.appspot.com"
      }
    6. 更新项目 web.xml 文件中的 API 入口点:
      • 将出现的所有 SystemServiceServlet 重命名为 EndpointsServlet
      • 将出现的所有路径 /_ah/spi/ 替换为所需的新路径 /_ah/api/

        以下代码标签页显示迁移前后 web.xml 的内容:

        迁移前

        Endpoints Frameworks 1.0 版 web.xml

        <servlet>
            <servlet-name>SystemServiceServlet</servlet-name>
            <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
            <init-param>
                <param-name>services</param-name>
                <param-value>com.example.helloendpoints.Greetings</param-value>
            </init-param>
            <init-param>
                <param-name>restricted</param-name>
                <param-value>false</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>SystemServiceServlet</servlet-name>
            <url-pattern>/_ah/spi/*</url-pattern>
        </servlet-mapping>

        迁移后

        Endpoints Frameworks 2.0 版 web.xml

        <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.helloendpoints.Greetings</param-value>
            </init-param>
            <init-param>
                <param-name>restricted</param-name>
                <param-value>false</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>EndpointsServlet</servlet-name>
            <url-pattern>/_ah/api/*</url-pattern>
        </servlet-mapping>

    7. 修改依赖项后,使用以下命令清理项目:
      gradle clean
    8. 您可以使用以下命令生成发现文档:
      gradle endpointsDiscoveryDocs
      详细了解 Gradle Endpoints Frameworks 插件任务
    9. 您可以使用以下命令部署项目:
      gradle appengineDeploy

      详细了解 Gradle App Engine 插件任务

验证新的部署

您可以验证新框架是否正在处理流量:

  1. 向新部署发送一些请求。
  2. 访问项目的日志查看器。

    转到“日志查看器”页面

  3. 如果其中显示的请求包含以 /_ah/api 开头的路径,则说明 Endpoints Frameworks 2.0 版当前正在为您的 API 提供服务。日志中不应显示路径以 /_ah/spi 开头的任何请求。这些请求表明 Endpoints Frameworks 1.0 版代理仍在为请求提供服务。

使用 Guice 配置适用于 Java 的 Endpoints Frameworks

若要使用 Guice,请执行以下操作:

  1. 添加新版 Endpoints Frameworks Guice 依赖项:

    Maven

    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-framework-guice</artifactId>
        <version>2.2.1</version>
    </dependency>

    Gradle

    compile 'com.google.endpoints:endpoints-framework-guice:2.0.9'
  2. 声明一个用于扩展 EndpointsModule 的新模块并对其进行配置,如下所示:
    public class EchoEndpointModule extends EndpointsModule {
      @Override
      public void configureServlets() {
        super.configureServlets();
    
        bind(ServiceManagementConfigFilter.class).in(Singleton.class);
        filter("/_ah/api/*").through(ServiceManagementConfigFilter.class);
    
        Map<String, String> apiController = new HashMap<String, String>();
        apiController.put("endpoints.projectId", "YOUR-PROJECT-ID");
        apiController.put("endpoints.serviceName", "YOUR-PROJECT-ID.appspot.com");
    
        bind(GoogleAppEngineControlFilter.class).in(Singleton.class);
        filter("/_ah/api/*").through(GoogleAppEngineControlFilter.class, apiController);
    
        bind(Echo.class).toInstance(new Echo());
        configureEndpoints("/_ah/api/*", ImmutableList.of(Echo.class));
      }
    }

添加 Endpoints API 管理

使用 Endpoints Frameworks 2.0 版,您还可以开启 API 管理功能,其中包括:

  • API 密钥管理
  • API 共享
  • 用户身份验证
  • API 指标
  • API 日志

要开始使用上述功能和其他 Endpoints Frameworks 2.0 版功能,请转到 Java 版适用于 App Engine 的 Endpoints Frameworks

问题排查

本部分介绍迁移到 Endpoints Frameworks 2.0 版时一些常见的异常行为以及建议的解决方案。

API 返回 404 错误,但 API Explorer 仍会正确列出 API

迁移到 Endpoints Frameworks 2.0 版时,您需要移除旧版 Endpoints Frameworks 1.0 版配置。如果应用配置中仍然存在旧版配置,则 Endpoints 服务会继续将该应用视为 1.0 版应用。您可能会在 App Engine 日志中看到发送到 /_ah/spi 的请求,这些请求会导致系统向客户端发送 HTTP 404 错误。

请从 web.xml 中移除以下行(如果存在):

<servlet>
    <servlet-name>SystemServiceServlet</servlet-name>
    <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
    <init-param>
        <param-name>services</param-name>
        <param-value>...</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SystemServiceServlet</servlet-name>
    <url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>

API 抛出反射错误

您只能将 endpoints-framework 工件封装到您的应用中,而不能封装旧版 appengine-endpoints JAR。如果部署的应用同时包含这两个 JAR,则可能会发生反射错误或运行时类型错误,例如 NoClassDefFoundErrorNoSuchMethodErrorClassCastException。请从构建文件中移除以下行(如果存在):

Maven

<dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-endpoints</artifactId>
      <version>1.9.53</version>
</dependency>

Gradle

compile group: 'com.google.appengine', name: 'appengine-endpoints', version: '+'

此外,如果其他任何依赖项依赖旧版 Guava,系统也可能指示缺少 TypeToken 方法。请务必使用 Guava v19 或使用 endpoints-framework-all 工件,以隐藏依赖项。

客户端库来源未编译

如果您看到诸如 method does not override or implement a method from a supertypecannot find symbol method setBatchPath(String) 之类的错误,这说明您的客户端应用可能依赖旧版 Google Java 客户端库。请务必确保 google-api-client 工件为 1.23.0 或更高版本。

Maven

<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.23.0</version>
</dependency>

Gradle

compile group: 'com.google.api-client', name: 'google-api-client', version: '1.23.0'

IJPA/JDO Datanucleus 增强功能问题

Maven

基于 Cloud SDK 的新版 App Engine Maven 插件不支持任何类型的 Datanucleus 增强功能。如果您的项目使用旧版插件中支持的 Datanucleus JDO 或 JPA 增强功能,则必须在迁移时单独配置第三方 Datanucleus Maven 插件。如需了解详情,请参阅以下内容:

Gradle

如果您的项目使用 gradle-appengine-plugin JPA/JDO Datanucleus 增强功能,则在改用基于 Cloud SDK 的新版 Gradle 插件后,必须手动配置 Datanucleus 增强功能。请参阅 Stackoverflow 中的示例

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
App Engine Cloud Endpoints Frameworks
需要帮助?请访问我们的支持页面