Esta página descreve como configurar as opções de configuração avançadas para provedores de tipos, como mapeamentos de entrada e propriedades virtuais. Para saber mais sobre tipos, leia Visão geral de tipos. Para saber mais sobre provedores de tipos, leia o Guia de uma página sobre como fazer a integração com o Deployment Manager.
Para integrar uma API que não cumpre os requisitos de API definidos pelo Deployment Manager, use os mapeamentos de entrada e as propriedades virtuais como auxílio para solucionar as inconsistências. Com os mapeamentos de entrada, você pode fornecer mapeamentos explícitos dos parâmetros da API com ambiguidades. As propriedades virtuais, por sua vez, permitem expor propriedades arbitrárias que não existem nas APIs subjacentes. Assim, você pode simplificar a entrada e ocultar as complexidades da API dos usuários.
Implementar as opções de configuração avançadas exige uma grande familiaridade com a API para a qual você está criando o provedor de tipos. Como as APIs podem ser muito diferentes umas das outras, esta página fornece orientações e exemplos gerais, e não para uma API específica.
Antes de começar
- Para usar os exemplos de linha de comando deste guia, instale a ferramenta de linha de comando "gcloud".
- Para usar os exemplos de API deste guia, configure o acesso de API.
- Configure o acesso à API v2beta para usar os exemplos de API deste guia.
- Entenda como criar uma configuração.
Cenários comuns que exigem opções de configuração avançadas
O nome da propriedade é reutilizado com valores diferentes
No caso de determinadas APIs, o mesmo nome de propriedade ou parâmetro é usado novamente em diferentes métodos, mas com valores diferentes. Por exemplo, uma API pode especificar que o parâmetro name
para criar um recurso (uma solicitação POST
) pode ter o valor foo/bar
enquanto o mesmo campo name
pode exigir o valor foo/bar/baz
para solicitações de atualização (PATCH
ou PUT
).
Os valores de propriedade podem ser inferidos a partir da resposta da API
Alguns métodos de API exigem o valor gerado pelo servidor, que é retornado quando é feita uma solicitação GET
para o recurso. Por exemplo, uma API pode exigir um parâmetro etag
para fazer solicitações de atualização ao alterar um recurso. O valor etag
é alterado após cada solicitação mudança. Portanto, você recebe o parâmetro etag
atual realizando uma solicitação GET
ao recurso antes de fazer a solicitação de atualização do recurso.
Ao usar mapeamentos de entrada, é possível informar ao Deployment Manager que o campo etag
pode ser recuperado do recurso da API. O Deployment Manager executa automaticamente uma solicitação GET
para conseguir esse valor quando um usuário chama o método que especificado nos mapeamentos de entrada.
Simplificação da entrada de usuários
O Deployment Manager oferece suporte para propriedades virtuais. Essas são propriedades arbitrárias que podem ser expostas aos usuários para diferentes usos por meio do Deployment Manager. Trate as propriedades virtuais como se não existissem propriedades na API de base, mas sim variáveis arbitrárias em que o valor será inserido por você nos mapeamentos de entrada. Por exemplo, imagine que haja uma propriedade da API que precisa ser codificada em base64 antes que o valor seja enviado à API de base. Em vez de pedir a seus usuários que informem o valor na codificação em base64, crie uma propriedade virtual que solicite o valor em texto simples, codifique-o em base64 com mapeamentos de entrada e forneça o resultado à API de base.
Como especificar as opções avançadas
Para especificar opções avançadas, forneça a propriedade collectionOverrides
ao criar seu recurso de provedor de tipos e defina mapeamentos de entrada ou propriedades virtuais para cada conjunto de API, conforme necessário.
Por exemplo, com a CLI gcloud, é possível fornecer opções avançadas usando um
arquivo YAML que será fornecido com sua solicitação type-providers create
.
Um exemplo de arquivo YAML pode ser similar ao seguinte:
collectionOverrides:
- collection: /emailAddresses/v1beta/people
options:
inputMappings:
- methodMatch: ^create$
fieldName: emailAddress.displayName
value: $.resource.properties.displayName
location: BODY
- methodMatch: ^update$
fieldName: displayName
value: $.resource.properties.displayName
location: PATH
virtualProperties: |
schema: http://json-schema.org/draft-04/schema#
type: object
properties:
displayName:
type: string
credential:
basicAuth:
user: [USERNAME]
password: [PASSWORD]
Essas configurações passam as seguintes instruções ao Deployment Manager:
Para o método
create
, procure o campo denominadoemailAddress.displayName
no corpo do recurso e defina o respectivo valor como a entrada do usuário para a propriedadedisplayName
na configuração do Deployment Manager. Portanto, se um usuário definir a própria configuração da seguinte forma:resources: - name: example type: myproject/emailAddress:/emailAddresses/v1beta/people properties: - displayName: John Doe ...
o Deployment Manager definirá o valor de
emailAddress.displayName
como "John Doe".Para o método
update
, o campo está no caminho do recurso e não no corpo do recurso, mas é aplicado o mesmo mapeamento de entrada.
Como especificar mapeamentos de entrada
O mapeamento de entrada permite mapear ou inserir informações em determinados campos da API. Desse modo, o Deployment Manager consegue interagir de maneira mais harmoniosa com a API de base. Isso alivia a responsabilidade dos usuários de ter que entender o comportamento sutil da API.
Use mapeamentos de entrada para simplificar a interação dos usuários com a API. Por exemplo, use mapeamentos de entrada para receber automaticamente valores gerados pelo servidor, como impressões digitais, IDs ou ETags. Isso evita que os usuários tenham o trabalho de executar uma solicitação get
separada no recurso sempre que quiserem fazer uma atualização.
Da mesma forma, também é possível usar os mapeamentos de entrada para lidar com situações ambíguas ou confusas, em que o mesmo campo da API tem valores distintos para métodos diferentes.
Por exemplo, uma solicitação para criar um recurso pode exigir uma propriedade name
que o usuário pode especificar, mas a mesma API pode exigir uma propriedade name
em um formato diferente para métodos update
. Assim, é possível usar mapeamentos de entrada para informar ao Deployment Manager qual valor é apropriado para cada método de API.
Para especificar mapeamentos de entrada para um provedor de tipos, forneça a propriedade options.inputMappings
. É possível definir os mapeamentos de entrada que se aplicam à API por inteiro ou fornecer explicitamente aqueles aplicáveis a cada coleção:
# Input mappings for the entire API
"options": {
"inputMappings": [
{
"fieldName": "[NAME]",
"location": "[PATH | BODY | QUERY | HEADER]",
"methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
"value": "[VALUE_TO_INJECT]"
},
{
"fieldName": "[NAME]",
"location": "[PATH | BODY | QUERY | HEADER]",
"methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
"value": "[VALUE_TO_INJECT]"
}
]
},
# Input mappings for specific collections
"collectionOverrides": [
{
"collection": "[SPECIFIC_COLLECTION]",
"options": {
"inputMappings": [
{
"fieldName": "[NAME]",
"location": "[PATH | BODY | QUERY | HEADER]",
"methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
"value": "[VALUE_TO_INJECT]"
},
{
"fieldName": "[NAME]",
"location": "[PATH | BODY]",
"methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
"value": "[VALUE_TO_INJECT]"
},
...[additional fields if necessary]...
]
}
}
]
Todas as partes importantes dessa sintaxe estão descritas abaixo.
Coleta
[SPECIFIC_COLLECTION]
é a coleção da API à que o mapeamento de entrada se aplica. Por exemplo, se você estiver fornecendo mapeamentos de entrada para um documento do Google Discovery, como a API IAM Service Accounts, os conjuntos relevantes são projects.serviceAccounts
e projects.serviceAccountKeys
.
Para uma API que usa a especificação OpenAPI, o caminho da coleção pode ser /example-collection/{name}
. Explore um exemplo de OpenAPI funcional no repositório da OpenAPI no GitHub.
Nome do campo
"fieldName"
é o atributo da API ou a propriedade para que você quer especificar o mapeamento de entrada. Por exemplo, "fieldName": "fingerprint", "fieldName": "etag"
e assim por diante.
Local
As propriedades da API podem aparecer como parâmetros no caminho do URL ou como parte do corpo da solicitação ou da resposta. Especifique como local onde o mapeamento de entrada se aplica, como o PATH
do URL ou o BODY
da solicitação. Os valores aceitos são:
PATH
BODY
QUERY
HEADER
Correspondência de métodos
Especifique a quais métodos o mapeamento de entrada se aplica. Use regex para especificar vários métodos. Por exemplo:
"methodMatch":"^create$"
Para as especificações da OpenAPI, você pode fazer:
"methodMatch: ^(put|get|delete|post)$"
Value
Especifique o valor que o Deployment Manager deve inserir nesse campo.
O campo usa a notação JSONPath.
Por exemplo, neste mapeamento de entrada está definido que, para o campo name
, o Deployment Manager deve receber o valor fornecido pelo usuário e injetá-lo no formato projects/$.project/topics/$resource.properties.topic
:
"inputMappings":[
{
"fieldName":"name",
"location":"PATH",
"methodMatch":"^post$",
"value":"concat(\"projects/\", $.project, \"/topics/\", $.resource.properties.topic)"
}...
Ao usar
$.resource.properties.[VARIABLE]
, você define o valor de uma propriedade que o usuário definirá na respectiva configuração. Por exemplo, para$.resource.properties.topic
, o valor será o que for informado pelo usuário para a propriedadetopic
na configuração dele:resources: - name: example type: example-type-provider:collectionA properties: topic: history # The value of "history" would be used for the `name` parameter because of the input mapping above
Para se referir ao próprio recurso após uma solicitação
get
, use$.resource.self.[VARIABLE]
. Por exemplo, para solicitações de atualização, se você quiser a impressão digital mais recente, poderá usar esta sintaxe para instruir o Deployment Manager a executar umaget
e reter o valor:{ 'fieldName': 'fingerprint', 'location': 'BODY', 'methodMatch': '^(put)$', # self represents the resource by doing a GET on it. # This mappings gets latest fingerprint on the request. # Final PUT Body will be # { # "name": "my-resource-name", # "fingerprint": "<server generated fingerprint>" # } 'value': '$.resource.self.fingerprint' }
Como usar propriedades virtuais
Propriedades virtuais são propriedades arbitrárias que podem ser expostas aos usuários por meio do Deployment Manager. Essas propriedades não fazem parte da API subjacente. Elas são variáveis arbitrárias que podem ser usadas para transmitir informações ou ocultar dos usuários as inconsistências na API. Você também pode fazer referência a propriedades virtuais nos mapeamentos de entrada.
As propriedades virtuais seguem o esquema JSON 4. Forneça as propriedades virtuais como parte de options
para uma coleção específica:
"collection": "[SPECIFIC_COLLECTION]",
"options": {
"virtualProperties": "schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n [PROPERTY]:\n type: [DATA_TYPE]\n [ANOTHER_PROPERTY]:\n type: [ANOTHER_DATA_TYPE]n"
"inputMappings": [
...
]
}
Em um arquivo de definição de YAML, a aparência fica assim:
- collection: projects.serviceAccounts
options:
virtualProperties: |
schema: http://json-schema.org/draft-04/schema#
type: object
properties:
a-property:
type : string
b-property:
type : string
required:
- a-property
- b-property
inputMappings:
...
Por exemplo, imagine uma API falsa que gera endereços de e-mail. Suponhamos que a API tenha um método para criar um e-mail que aceite uma propriedade emailAddress.displayName
. Quando um usuário quer criar um endereço de e-mail, ele envia a seguinte solicitação:
POST https://example.com/emailAddresses/v1beta/people/
{
"emailAddress": {
"displayName": "john"
}
}
Digamos que a API exiba uma maneira de atualizar o endereço de e-mail, mas o método para atualizar um e-mail requeira apenas a propriedade displayName
em vez da propriedade email.displayName
:
POST https://example.com/emailAddresses/v1beta/people/john
{
"displayName": "josh"
}
Como os usuários podem fornecer o valor ao usar esse provedor de tipos? Você pode pedir a eles que especifiquem a propriedade de uma maneira diferente, dependendo da operação:
# Creating an email
resources:
- name: example-config
type: projects/test-project:emailAddresses
properties:
emailAddress:
displayName: john
# Updating an email
resources:
- name: example-config
type: projects/test-project:emailAddresses
properties:
displayName: john
Como alternativa, é possível criar uma propriedade virtual que use o mesmo valor, independentemente da operação. Depois, use os mapeamentos de entrada para mapear a propriedade virtual para o parâmetro da API apropriado. Para este exemplo, supõem-se que você tenha definido uma propriedade virtual chamada displayName
. Os mapeamentos de entrada podem ter a seguinte aparência:
{
"collectionOverrides":[
{
"collection":"emailAddresses",
"options":{
"inputMappings":[
{
"fieldName":"emailAddress.displayName",
"location":"BODY",
"methodMatch":"^create$",
"value":"$.resource.properties.displayName"
},
{
"fieldName":"displayName",
"location":"BODY",
"methodMatch":"^update$",
"value":"$.resource.properties.displayName"
}
],
"virtualProperties":"schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n displayName:\n type: string\nrequired:\n- displayName\n"
}
}
],
"descriptorUrl":"https://example.com/emailAddresses/v1beta/",
"options":{
"nameProperty":""
}
}
Especificamente, a propriedade virtual está definida aqui:
"virtualProperties":"schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n displayName:\n type: string\nrequired:\n- displayName\n"
Em formato legível por humanos:
"virtualProperties":
"schema: http://json-schema.org/draft-04/schema#\n
type: object\n
properties:\n
displayName:\n
- type: string\n
required:\n
- displayName\n"
Agora, seus usuários podem especificar displayName
como a propriedade de nível superior para solicitações de atualização e criação, e o Deployment Manager saberá como mapear o valor corretamente.
# Creating an email
resources:
- name: example-config
type: projects/test-project:emailAddresses
properties:
displayName: john
# Updating an email
resources:
- name: example-config
type: projects/test-project:emailAddresses
properties:
displayName: john
A seguir
- Saiba como usar um provedor de tipos.
- Saiba mais sobre tipos.
- Leia sobre como criar uma configuração.
- Criar uma implantação.
- Saiba como criar um tipo composto.