遷移至 App Engine 適用的 Cloud Endpoints Frameworks 2.0 版

本頁面說明如何使用 Java 將現有的 Cloud Endpoints 1.0 版應用程式遷移至 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 方法

此外,Endpoints 1.0 版適用的 Android Studio 支援目前不支援 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. 下載並初始化 Google Cloud CLI
  2. 執行下列指令:
    1. 確認 gcloud CLI 已獲授權,可存取您在 Google Cloud上的資料和服務:
      gcloud auth login
    2. 使用應用程式預設憑證:
      gcloud auth application-default login
    3. 安裝 Google Cloud SDK app-engine-java 元件:
      gcloud components install app-engine-java
    4. 將 Google Cloud SDK 以及所有元件更新至最新版本:
      gcloud components update

使用 Maven 或 Gradle 進行遷移

Maven

  1. 移除舊版的相依項目,即 appengine-endpoints 構件:
    <dependency>
          <groupId>com.google.appengine</groupId>
          <artifactId>appengine-endpoints</artifactId>
          <version>1.9.53</version>
    </dependency>
  2. 新增新的 Endpoints Framework 依附元件:
    <dependency>
        <groupId>com.google.endpoints</groupId>
        <artifactId>endpoints-framework</artifactId>
        <version>2.2.1</version>
    </dependency>
  3. 新增 Endpoints Framework 外掛程式,並定義生成探索文件的主機名稱:
    <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 Framework 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 Framework 外掛程式:
    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 Framework 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 的外掛程式工作

使用 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));
      }
    }

驗證新的部署

您可以執行以下方法,驗證新的框架是否正在提供流量:

  1. 傳送一些要求到新的部署。
  2. 在 Google Cloud 控制台中,依序前往「Logging」 >「Logs Explorer」頁面。

    前往「Logs Explorer」頁面

  3. 如果要求顯示的路徑以 /_ah/api 做為開頭,則 Endpoints Frameworks 2.0 版現在正為您的 API 提供流量。記錄不應顯示任何以 /_ah/spi 做為路徑開頭的要求,這些要求指出 Endpoints 1.0 Proxy 仍在處理要求。

新增 Endpoints API 管理

Endpoints Frameworks 2.0 版也可讓您開啟 API 管理功能,其中包括:

  • API 金鑰管理
  • API 共用
  • 使用者驗證
  • API 指標
  • API 記錄

如要開始使用這些功能,請參閱新增 API 管理一文。

疑難排解

本節說明遷移到 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 錯誤發送至用戶端。

  1. 如果 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>
    
  2. 確認您的 web.xml 檔案包含下列幾行:

    <servlet-mapping>
        <servlet-name>EndpointsServlet</servlet-name>
        <url-pattern>/_ah/api/*</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 19.0 版或是 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'

JPA/JDO Datanucleus 強化的問題

Maven

以 Google Cloud CLI 為基礎的新型 App Engine Maven 外掛程式不支援任何類型的 Datanucleus 強化功能。如果您的專案使用舊外掛程式的 Datanucleus JDO 或 JPA 強化支援功能,則必須在遷移時單獨設定第三方 Datanucleus Maven 外掛程式。詳情請參閱下列說明:

Gradle

如果您的專案使用 gradle-appengine-plugin JPA/JDO Datanucleus 強化功能,您必須在切換至以 gcloud CLI 為基礎的新 Gradle 外掛程式之後,手動設定 Datanucleus 強化功能。請參閱 Stackoverflow 的範例