Como migrar para o Cloud Endpoints Frameworks versão 2.0 para App Engine

Nesta página, você aprenderá a migrar um aplicativo atual do Cloud Endpoints versão 1.0 para o Endpoints Frameworks para App Engine em Java.

Vantagens

Existem vários benefícios no novo framework, incluindo:

  • latência reduzida de solicitação;
  • melhor integração com os recursos do App Engine (como domínios personalizados);
  • suporte oficial para configurações do Guice;
  • opcionalmente, novos recursos de gerenciamento de API.

O Endpoints Frameworks versão 2.0 não afeta as interfaces com a API. Os clientes atuais continuam a funcionar depois da migração sem alterações de código no lado do cliente.

Recursos e ferramentas excluídos no momento

Os recursos a seguir não estão disponíveis no momento. Se precisar de algum deles, envie uma solicitação de recurso.

  • Protocolo JSON-RPC, obrigatório para clientes iOS legados. Para criar clientes iOS para a API do Endpoints Frameworks 2.0, recomenda-se usar a biblioteca de cliente Objective-C de APIs do Google para APIs REST (em inglês)
  • ETags automáticos
  • Campos de tipo automáticos
  • Integração de ambiente de desenvolvimento integrado (IDE, na sigla em inglês)
  • Respostas parciais de fields
  • Criação automática de método da API PATCH

Além disso, o suporte do Android Studio para Endpoints versão 1.0 ainda não é compatível com a versão 2.0.

Como migrar para o Endpoints Frameworks versão 2.0

O Endpoints Frameworks versão 2.0 foi migrado para os artefatos Maven no grupo com.google.endpoints. O JAR obrigatório de base está no artefato endpoints-framework. Se quiser usar a configuração do Guice, adicione o artefato endpoints-framework-guice.

Com as seguintes instruções, você aprenderá a migrar do Endpoints Frameworks versão 1.0 para o Endpoints Frameworks versão 2.0 usando um documento de descoberta:

  • Faça o download e inicialize o SDK do Cloud.
  • Execute os seguintes comandos:
    1. Verifique se o SDK do Cloud está autorizado a acessar seus dados e serviços no Google Cloud:
      gcloud auth login
    2. Use o Application Default Credentials:
      gcloud auth application-default login
    3. Instale o componente app-engine-java do SDK do Cloud:
      gcloud components install app-engine-java
    4. Atualize para a versão mais recente do SDK do Cloud e todos os componentes:
      gcloud components update
  • Migrar usando Maven ou Gradle:

    Maven

    1. Remova a dependência legada, que é o artefato appengine-endpoints:
      <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-endpoints</artifactId>
            <version>1.9.53</version>
      </dependency>
    2. Adicione a nova dependência do Endpoints Frameworks:
      <dependency>
          <groupId>com.google.endpoints</groupId>
          <artifactId>endpoints-framework</artifactId>
          <version>2.2.1</version>
      </dependency>
    3. Adicione o novo plug-in do Endpoints Frameworks e defina o nome do host para um documento de descoberta gerado:
      <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. Adicione o novo plug-in do Maven para App Engine:
      <plugin>
          <groupId>com.google.cloud.tools</groupId>
          <artifactId>appengine-maven-plugin</artifactId>
          <version>1.3.2</version>
          <configuration>
              <!-- deploy configuration -->
          </configuration>
      </plugin>
    5. Atualize o ponto de entrada da API no arquivo web.xml do projeto:
      • Renomeie todas as ocorrências de SystemServiceServlet a EndpointsServlet.
      • Substitua todas as ocorrências do caminho /_ah/spi/ pelo novo caminho obrigatório /_ah/api/.

      Veja a seguir o conteúdo de web.xml antes e depois da migração:

      Antes da migração

      web.xml do Endpoints Frameworks versão 1.0:
      <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>

      Depois da migração

      web.xml do Endpoints Frameworks versão 2.0:
      <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. Depois de modificar as dependências, limpe o projeto usando:
      mvn clean
    7. É possível gerar um documento de descoberta:
      mvn endpoints-framework:discoveryDocs
      Saiba mais sobre as metas de plug-in do Maven Endpoints Frameworks.
    8. É possível implantar um projeto:
      mvn appengine:deploy

      Saiba mais sobre as metas do plug-in do Maven App Engine Plugin.

    Gradle

    1. Remova a dependência legada, que é o artefato appengine-endpoints:
      compile group: 'com.google.appengine', name: 'appengine-endpoints', version: '+'
    2. Adicione a nova dependência do Endpoints Frameworks:
      compile group: 'com.google.endpoints', name: 'endpoints-framework', version: '2.0.8'
    3. Adicione os novos plug-ins do App Engine e do 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. Aplique os novos plug-ins do App Engine e do Endpoints Frameworks:
      apply plugin: 'com.google.cloud.tools.appengine'
      apply plugin: 'com.google.cloud.tools.endpoints-framework-server'
    5. Defina o endpoint de nome do host para documentos de descoberta gerados:
      endpointsServer {
        // Endpoints Framework Plugin server-side configuration
        hostname = "YOUR-PROJECT-ID.appspot.com"
      }
    6. Atualize o ponto de entrada da API no arquivo web.xml do projeto:
      • Renomeie todas as ocorrências de SystemServiceServlet a EndpointsServlet.
      • Substitua todas as ocorrências do caminho /_ah/spi/ pelo novo caminho obrigatório /_ah/api/.

      Veja a seguir o conteúdo de web.xml antes e depois da migração:

      Antes da migração

      web.xml do Endpoints Frameworks versão 1.0:
      <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>

      Depois da migração

      web.xml do Endpoints Frameworks versão 2.0:
      <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. Depois de modificar as dependências, limpe o projeto usando:
      gradle clean
    8. Gere um documento de descoberta usando:
      gradle endpointsDiscoveryDocs
      Saiba mais sobre as tarefas de plug-in do Gradle Endpoints Frameworks.
    9. Para implantar um projeto, use:
      gradle appengineDeploy

      Saiba mais sobre as tarefas de plug-in do Gradle App Engine Plugin.

    Como usar o Guice para configurar o Endpoints Frameworks para Java

    Se quiser usar Guice:

    1. Adicione a nova dependência do Endpoints Frameworks:

      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. Declare um novo módulo que estenda o EndpointsModule, após isso, configure-o da seguinte maneira:
      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));
        }
      }

    Como verificar uma nova implantação

    Verifique se o novo framework está veiculando tráfego:

    1. Envie algumas solicitações para a nova implantação.
    2. No Console do Cloud, acesse a página Stackdriver Logging > Registros (visualizador de registros).

      Ir para a página "Logs Viewer"

    3. Se as solicitações forem exibidas com caminhos que começam com /_ah/api, o Endpoints Frameworks versão 2.0 exibirá a API. Os registros não podem mostrar solicitações com caminhos que começam com /_ah/spi. Elas indicam que o proxy do Endpoints Frameworks versão 1.0 ainda está exibindo solicitações.

    Como adicionar gerenciamento da API do Endpoints

    O Endpoints Frameworks versão 2.0 também permite ativar recursos de gerenciamento de API, incluindo:

    • Gerenciamento de chaves de API
    • Compartilhamento da API
    • Autenticação de usuários
    • Métricas da API
    • registros da API.

    Para começar a usar esses recursos, consulte Como adicionar o gerenciamento da API.

    Resolver problemas

    Nesta seção, você verá os comportamentos erráticos comuns durante a migração para o Endpoints Frameworks versão 2.0 e as soluções sugeridas.

    A API retorna erros 404, mas a API Explorer continua a listar as APIs corretamente

    É obrigatória a remoção da antiga configuração do Endpoints Frameworks versão 1.0 na migração para o Endpoints Frameworks versão 2.0. Se a configuração antiga ainda estiver presente na configuração do aplicativo, o serviço do Endpoints continuará a tratá-lo como versão 1.0. É possível ver solicitações, nos registros do App Engine, enviadas para /_ah/spi, que resultam em erros HTTP 404 enviados ao cliente.

    1. Remova as seguintes linhas do arquivo web.xml, se estiverem presentes:

      <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. Verifique se o arquivo web.xml contém o seguinte:

      <servlet-mapping>
          <servlet-name>EndpointsServlet</servlet-name>
          <url-pattern>/_ah/api/*</url-pattern>
      </servlet-mapping>
      

    API com erros de reflexão

    Apenas o artefato endpoints-framework precisar estar no pacote do aplicativo. O JAR appengine-endpoints antigo não é necessário. Implantar um aplicativo com os dois JARs pode causar erros de reflexão ou de tipo de ambiente de execução, como NoClassDefFoundError, NoSuchMethodError e ClassCastException. Remova as seguintes linhas do arquivo de compilação, se estiverem presentes:

    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: '+'

    Além disso, se alguma das outras dependências precisar de versões mais antigas do Guava, esse erro também se manifestará como um método TypeToken ausente. Use o Guava v19 ou o artefato endpoints-framework-all, que controla as dependências.

    Fontes da biblioteca de cliente não compilam

    Se aparecerem erros, como method does not override or implement a method from a supertype ou cannot find symbol method setBatchPath(String), o aplicativo cliente provavelmente depende de uma versão antiga da biblioteca de cliente do Google para Java. É preciso garantir que o artefato google-api-client seja 1.23.0 ou superior.

    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'

    Problemas com o aprimoramento do DataNucleus JPA/JDO

    Maven

    O novo plug-in do Maven para App Engine baseado no SDK do Cloud não oferece suporte a nenhum aprimoramento do Datanucleus. Se o projeto usa o suporte ao aprimoramento JDO ou JPA do Datanucleus do plug-in antigo, configure o plug-in do Maven para Datanucleus de terceiros separadamente ao migrar. Para saber mais, consulte os seguintes artigos:

    Gradle

    Se o projeto usa o aprimoramento de gradle-appengine-plugin JPA/JDO DataNucleus, é preciso configurá-lo manualmente, depois de mudar para o novo plug-in Gradle baseado no SDK do Cloud. Veja um exemplo do Stackoverflow (em inglês).