Crie um esquema para um tópico

Este documento mostra como criar esquemas para tópicos Pub/Sub.

Antes de começar

Antes de criar um esquema, conclua o seguinte:

Funções e autorizações necessárias

Para obter as autorizações de que precisa para criar e gerir esquemas, peça ao seu administrador que lhe conceda a função IAM Editor do Pub/Sub (roles/pubsub.editor) no seu projeto. Para mais informações sobre a atribuição de funções, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.

Esta função predefinida contém as autorizações necessárias para criar e gerir esquemas. Para ver as autorizações exatas que são necessárias, expanda a secção Autorizações necessárias:

Autorizações necessárias

São necessárias as seguintes autorizações para criar e gerir esquemas:

  • Crie um esquema: pubsub.schemas.create
  • Anexe o esquema ao tópico: pubsub.schemas.attach
  • Confirme uma revisão do esquema: pubsub.schemas.commit
  • Elimine um esquema ou uma revisão de esquema: pubsub.schemas.delete
  • Obtenha um esquema ou revisões de esquemas: pubsub.schemas.get
  • Esquemas de listas: pubsub.schemas.list
  • Revisões do esquema de listas: pubsub.schemas.listRevisions
  • Reverta um esquema: pubsub.schemas.rollback
  • Validar uma mensagem: pubsub.schemas.validate
  • Obtenha a Política IAM para um esquema: pubsub.schemas.getIamPolicy
  • Configure a Política IAM para um esquema: pubsub.schemas.setIamPolicy

Também pode conseguir estas autorizações com funções personalizadas ou outras funções predefinidas.

Pode conceder funções e autorizações a responsáveis como utilizadores, grupos, domínios ou contas de serviço. Pode criar um esquema num projeto e anexá-lo a um tópico localizado num projeto diferente. Certifique-se de que tem as autorizações necessárias para cada projeto.

Crie um esquema

Pode criar um esquema através da Google Cloud consola, da CLI gcloud, da API Pub/Sub ou das bibliotecas cliente da Google Cloud.

Antes de criar um esquema, reveja estas informações importantes sobre esquemas.

Consola

Para criar um esquema, siga estes passos:

  1. Na Google Cloud consola, aceda à página Esquemas do Pub/Sub.

    Aceda a Esquemas

  2. Clique em Criar esquema.

  3. No campo ID do esquema, introduza um ID para o seu esquema.

    Para ver diretrizes sobre como atribuir um nome a um esquema, consulte o artigo Diretrizes para atribuir um nome a um tópico, uma subscrição ou uma imagem instantânea.

  4. Para o Tipo de esquema, selecione Avro ou Protocol Buffer.

    Saiba mais sobre os tipos de esquemas.

  5. No campo Definição do esquema, introduza a definição Avro ou Protocol Buffer do seu esquema.

    Por exemplo, segue-se um esquema de amostra em Avro.

    {
      "type": "record",
      "name": "Avro",
      "fields": [
        {
          "name": "ProductName",
          "type": "string",
          "default": ""
        },
        {
          "name": "SKU",
          "type": "int",
          "default": 0
        },
        {
          "name": "InStock",
          "type": "boolean",
          "default": false
        }
      ]
    }
    
    
  6. Opcional: clique em Validar definição para verificar se a definição do esquema está correta.

    A verificação de validação não verifica a compatibilidade do esquema com as mensagens a publicar. Teste as mensagens no passo seguinte.

  7. Opcional: pode testar se as mensagens com o esquema correto são publicadas.

    1. Clique em Testar mensagem.

    2. Na janela Mensagem de teste, selecione um tipo de Codificação de mensagens.

    3. No Corpo da mensagem, introduza uma mensagem de teste.

    4. Clique em Testar.

      Por exemplo, segue-se uma mensagem de exemplo para o esquema de teste. Neste exemplo, selecione a Codificação de mensagens como JSON.

      {"ProductName":"GreenOnions", "SKU":34543, "InStock":true}
      
    5. Saia da página de mensagens de teste.

  8. Clique em Criar para guardar o esquema.

gcloud

gcloud pubsub schemas create SCHEMA_ID \
        --type=SCHEMA_TYPE \
        --definition=SCHEMA_DEFINITION

Onde:

  • SCHEMA_TYPE é avro ou protocol-buffer.
  • SCHEMA_DEFINITION é um string que contém a definição do esquema, formatado de acordo com o tipo de esquema escolhido.

Também pode especificar a definição do esquema num ficheiro:

gcloud pubsub schemas create SCHEMA_ID \
        --type=SCHEMA_TYPE \
        --definition-file=SCHEMA_DEFINITION_FILE

Onde:

  • SCHEMA_TYPE é avro ou protocol-buffer.
  • SCHEMA_DEFINITION_FILE é um string que contém o caminho para o ficheiro com a definição do esquema, formatado de acordo com o tipo de esquema escolhido.

REST

Para criar um esquema, envie um pedido POST da seguinte forma:

POST https://pubsub.googleapis.com/v1/projects/PROJECT_ID/schemas?schemaId=SCHEMA_ID
Authorization: Bearer $(gcloud auth application-default print-access-token)
Content-Type: application/json --data @response-body.json

Especifique os seguintes campos no corpo do pedido:

{
  "definition": SCHEMA_DEFINITION
  "type": SCHEMA_TYPE
}

Onde:

  • SCHEMA_TYPE é avro ou protocol-buffer.
  • SCHEMA_DEFINITION é uma string que contém a definição do esquema, formatada de acordo com o tipo de esquema escolhido.

O corpo da resposta deve conter uma representação JSON de um recurso de esquema. Por exemplo:

{
  "name": SCHEMA_NAME,
  "type": SCHEMA_TYPE,
  "definition": SCHEMA_DEFINITION
  "revisionId": REVISION_ID
  "revisionCreateTime": REVISION_CREATE_TIME
}

Onde:

  • REVISION_ID é o ID gerado pelo servidor para a revisão.
  • REVISION_CREATE_TIME é a data/hora ISO 8601 em que a revisão foi criada.

C++

Antes de experimentar este exemplo, siga as instruções de configuração do C++ no artigo Início rápido: usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API C++ do Pub/Sub.

Avro

namespace pubsub = ::google::cloud::pubsub;
[](pubsub::SchemaServiceClient client, std::string const& project_id,
   std::string const& schema_id, std::string const& schema_definition_file) {
  std::string const definition = ReadFile(schema_definition_file);

  google::pubsub::v1::CreateSchemaRequest request;
  request.set_parent(google::cloud::Project(project_id).FullName());
  request.set_schema_id(schema_id);
  request.mutable_schema()->set_type(google::pubsub::v1::Schema::AVRO);
  request.mutable_schema()->set_definition(definition);
  auto schema = client.CreateSchema(request);
  if (schema.status().code() == google::cloud::StatusCode::kAlreadyExists) {
    std::cout << "The schema already exists\n";
    return;
  }
  if (!schema) throw std::move(schema).status();

  std::cout << "Schema successfully created: " << schema->DebugString()
            << "\n";
}

Proto

namespace pubsub = ::google::cloud::pubsub;
[](pubsub::SchemaServiceClient client, std::string const& project_id,
   std::string const& schema_id, std::string const& schema_definition_file) {
  std::string const definition = ReadFile(schema_definition_file);

  google::pubsub::v1::CreateSchemaRequest request;
  request.set_parent(google::cloud::Project(project_id).FullName());
  request.set_schema_id(schema_id);
  request.mutable_schema()->set_type(
      google::pubsub::v1::Schema::PROTOCOL_BUFFER);
  request.mutable_schema()->set_definition(definition);
  auto schema = client.CreateSchema(request);
  if (schema.status().code() == google::cloud::StatusCode::kAlreadyExists) {
    std::cout << "The schema already exists\n";
    return;
  }
  if (!schema) throw std::move(schema).status();
  std::cout << "Schema successfully created: " << schema->DebugString()
            << "\n";
}

C#

Antes de experimentar este exemplo, siga as instruções de configuração do C# no artigo Início rápido: usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API C# do Pub/Sub.

Avro


using Google.Api.Gax.ResourceNames;
using Google.Cloud.PubSub.V1;
using Grpc.Core;
using System;
using System.IO;

public class CreateAvroSchemaSample
{
    public Schema CreateAvroSchema(string projectId, string schemaId, string pathToDefinition)
    {
        SchemaServiceClient schemaService = SchemaServiceClient.Create();
        var schemaName = SchemaName.FromProjectSchema(projectId, schemaId);
        string schemaDefinition = File.ReadAllText(pathToDefinition);
        Schema schema = new Schema
        {
            SchemaName = schemaName,
            Type = Schema.Types.Type.Avro,
            Definition = schemaDefinition
        };
        CreateSchemaRequest createSchemaRequest = new CreateSchemaRequest
        {
            ParentAsProjectName = ProjectName.FromProject(projectId),
            SchemaId = schemaId,
            Schema = schema
        };

        try
        {
            schema = schemaService.CreateSchema(createSchemaRequest);
            Console.WriteLine($"Schema {schema.Name} created.");
        }
        catch (RpcException e) when (e.Status.StatusCode == StatusCode.AlreadyExists)
        {
            Console.WriteLine($"Schema {schemaName} already exists.");
        }
        return schema;
    }
}

Proto


using Google.Api.Gax.ResourceNames;
using Google.Cloud.PubSub.V1;
using Grpc.Core;
using System;
using System.IO;

public class CreateProtoSchemaSample
{
    public Schema CreateProtoSchema(string projectId, string schemaId, string pathToDefinition)
    {
        SchemaServiceClient schemaService = SchemaServiceClient.Create();
        var schemaName = SchemaName.FromProjectSchema(projectId, schemaId);
        string schemaDefinition = File.ReadAllText(pathToDefinition);
        Schema schema = new Schema
        {
            SchemaName = schemaName,
            Type = Schema.Types.Type.ProtocolBuffer,
            Definition = schemaDefinition
        };
        CreateSchemaRequest createSchemaRequest = new CreateSchemaRequest
        {
            ParentAsProjectName = ProjectName.FromProject(projectId),
            SchemaId = schemaId,
            Schema = schema
        };

        try
        {
            schema = schemaService.CreateSchema(createSchemaRequest);
            Console.WriteLine($"Schema {schema.Name} created.");
        }
        catch (RpcException e) when (e.Status.StatusCode == StatusCode.AlreadyExists)
        {
            Console.WriteLine($"Schema {schemaName} already exists.");
        }
        return schema;
    }
}

Ir

O exemplo seguinte usa a versão principal da biblioteca de cliente Go Pub/Sub (v2). Se ainda estiver a usar a biblioteca v1, consulte o guia de migração para a v2. Para ver uma lista de exemplos de código da v1, consulte os exemplos de código descontinuados.

Antes de experimentar este exemplo, siga as instruções de configuração do Go em Início rápido: usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Go Pub/Sub.

Avro

import (
	"context"
	"fmt"
	"io"
	"os"

	pubsub "cloud.google.com/go/pubsub/v2/apiv1"
	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
)

// createAvroSchema creates a schema resource from a JSON-formatted Avro schema file.
func createAvroSchema(w io.Writer, projectID, schemaID, avscFile string) error {
	// projectID := "my-project-id"
	// schemaID := "my-schema"
	// avscFile = "path/to/an/avro/schema/file(.avsc)/formatted/in/json"
	ctx := context.Background()
	client, err := pubsub.NewSchemaClient(ctx)
	if err != nil {
		return fmt.Errorf("pubsub.NewSchemaClient: %w", err)
	}
	defer client.Close()

	avscSource, err := os.ReadFile(avscFile)
	if err != nil {
		return fmt.Errorf("error reading from file: %s", avscFile)
	}

	req := &pubsubpb.CreateSchemaRequest{
		Parent: fmt.Sprintf("projects/%s", projectID),
		Schema: &pubsubpb.Schema{
			Type:       pubsubpb.Schema_AVRO,
			Definition: string(avscSource),
		},
		SchemaId: schemaID,
	}
	s, err := client.CreateSchema(ctx, req)
	if err != nil {
		return fmt.Errorf("error calling CreateSchema: %w", err)
	}
	fmt.Fprintf(w, "Schema created: %#v\n", s)
	return nil
}

Proto

import (
	"context"
	"fmt"
	"io"
	"os"

	pubsub "cloud.google.com/go/pubsub/v2/apiv1"
	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
)

// createProtoSchema creates a schema resource from a schema proto file.
func createProtoSchema(w io.Writer, projectID, schemaID, protoFile string) error {
	// projectID := "my-project-id"
	// schemaID := "my-schema"
	// protoFile = "path/to/a/proto/schema/file(.proto)/formatted/in/protocol/buffers"
	ctx := context.Background()
	client, err := pubsub.NewSchemaClient(ctx)
	if err != nil {
		return fmt.Errorf("pubsub.NewSchemaClient: %w", err)
	}
	defer client.Close()

	protoSource, err := os.ReadFile(protoFile)
	if err != nil {
		return fmt.Errorf("error reading from file: %s", protoFile)
	}

	req := &pubsubpb.CreateSchemaRequest{
		Parent: fmt.Sprintf("projects/%s", projectID),
		Schema: &pubsubpb.Schema{
			Type:       pubsubpb.Schema_PROTOCOL_BUFFER,
			Definition: string(protoSource),
		},
		SchemaId: schemaID,
	}
	s, err := client.CreateSchema(ctx, req)
	if err != nil {
		return fmt.Errorf("error calling CreateSchema: %w", err)
	}
	fmt.Fprintf(w, "Schema created: %#v\n",