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

Esta página descreve a migração de 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 ainda não estão disponíveis. 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:

  1. Faça o download e inicialize a Google Cloud CLI.
  2. Execute os seguintes comandos:
    1. Verifique se a CLI gcloud está autorizada 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 Google Cloud:
      gcloud components install app-engine-java
    4. Atualize para a versão mais recente do SDK Google 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.

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 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 e 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 alguns pedidos para a nova implantação.
  2. No console do Google Cloud, acesse a página Logging > Análise de registros.

    Acessar a página Análise de registros

  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 na Google Cloud CLI não oferece suporte a nenhum tipo de 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 configurar manualmente o aprimoramento do Datanucleus depois de mudar para o novo plug-in Gradle baseado na CLI gcloud. Veja um exemplo do Stackoverflow (em inglês).