Aprendendo a usar o GraphQL com AEM - Conteúdo de amostra e Query

Para começar a usar query GraphQL e como eles trabalham com AEM Fragmentos de conteúdo, é útil ver alguns exemplos práticos.

Para ajudar com isso, consulte:

GraphQL para AEM - Resumo das extensões

A operação básica de query com GraphQL para AEM obedece à especificação GraphQL padrão. Para query GraphQL com AEM há algumas extensões:

GraphQL - Query de amostra usando a Amostra da estrutura do fragmento do conteúdo

Consulte estes query de amostra para obter ilustrações de criação de query, juntamente com resultados de amostra.

OBSERVAÇÃO

Dependendo da sua instância, você pode acessar diretamente a interface Graph i QL incluída com AEM API do GraphQL para enviar e testar query.

Por exemplo: http://localhost:4502/content/graphiql.html

OBSERVAÇÃO

Query de amostra - Todos os Schemas e tipos de dados disponíveis

Isso retornará todos os types para todos os schemas disponíveis.

Query de amostra

{
  __schema {
    types {
      name
      description
    }
  }
}

Resultado da amostra

{
  "data": {
    "__schema": {
      "types": [
        {
          "name": "AdventureModel",
          "description": null
        },
        {
          "name": "AdventureModelArrayFilter",
          "description": null
        },
        {
          "name": "AdventureModelFilter",
          "description": null
        },
        {
          "name": "AdventureModelResult",
          "description": null
        },
        {
          "name": "AdventureModelResults",
          "description": null
        },
        {
          "name": "AllFragmentModels",
          "description": null
        },
        {
          "name": "ArchiveRef",
          "description": null
        },
        {
          "name": "ArrayMode",
          "description": null
        },
        {
          "name": "ArticleModel",
          "description": null
        },

...more results...

        {
          "name": "__EnumValue",
          "description": null
        },
        {
          "name": "__Field",
          "description": null
        },
        {
          "name": "__InputValue",
          "description": null
        },
        {
          "name": "__Schema",
          "description": "A GraphQL Introspection defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, the entry points for query, mutation, and subscription operations."
        },
        {
          "name": "__Type",
          "description": null
        },
        {
          "name": "__TypeKind",
          "description": "An enum describing what kind of type a given __Type is"
        }
      ]
    }
  }
}

Query de amostra - Todas as informações sobre todas as cidades

Para recuperar todas as informações sobre todas as cidades, você pode usar o query básico:
Query de amostra

{
  cityList {
    items
  }
}

Quando executado, o sistema expandirá automaticamente o query para incluir todos os campos:

{
  cityList {
    items {
      _path
      name
      country
      population
    }
  }
}

Resultados da amostra

{
  "data": {
    "cityList": {
      "items": [
        {
          "_path": "/content/dam/sample-content-fragments/cities/basel",
          "name": "Basel",
          "country": "Switzerland",
          "population": 172258
        },
        {
          "_path": "/content/dam/sample-content-fragments/cities/berlin",
          "name": "Berlin",
          "country": "Germany",
          "population": 3669491
        },
        {
          "_path": "/content/dam/sample-content-fragments/cities/bucharest",
          "name": "Bucharest",
          "country": "Romania",
          "population": 1821000
        },
        {
          "_path": "/content/dam/sample-content-fragments/cities/san-francisco",
          "name": "San Francisco",
          "country": "USA",
          "population": 883306
        },
        {
          "_path": "/content/dam/sample-content-fragments/cities/san-jose",
          "name": "San Jose",
          "country": "USA",
          "population": 1026350
        },
        {
          "_path": "/content/dam/sample-content-fragments/cities/stuttgart",
          "name": "Stuttgart",
          "country": "Germany",
          "population": 634830
        },
        {
          "_path": "/content/dam/sample-content-fragments/cities/zurich",
          "name": "Zurich",
          "country": "Switzerland",
          "population": 415367
        }
      ]
    }
  }
}

Query de amostra - Nomes de todas as cidades

Este é um query simples para retornar namede todas as entradas no schema city.

Query de amostra

query {
  cityList {
    items {
      name
    }
  }
}

Resultados da amostra

{
  "data": {
    "cityList": {
      "items": [
        {
          "name": "Basel"
        },
        {
          "name": "Berlin"
        },
        {
          "name": "Bucharest"
        },
        {
          "name": "San Francisco"
        },
        {
          "name": "San Jose"
        },
        {
          "name": "Stuttgart"
        },
        {
          "name": "Zurich"
        }
      ]
    }
  }
}

Query de amostra - Um único fragmento de cidade específico

Este é um query para retornar os detalhes de uma única entrada de fragmento em um local específico no repositório.

Query de amostra

{
  cityByPath (_path: "/content/dam/sample-content-fragments/cities/berlin") {
    item {
      _path
      name
      country
      population
     categories
    }
  }
}

Resultados da amostra

{
  "data": {
    "cityByPath": {
      "item": {
        "_path": "/content/dam/sample-content-fragments/cities/berlin",
        "name": "Berlin",
        "country": "Germany",
        "population": 3669491,
        "categories": [
          "city:capital",
          "city:emea"
        ]
      }
    }
  }
}

Query de amostra - Todas as cidades com uma Variação nomeada

Se você criar uma nova variação, chamada "Berlin Center" (berlin_centre), para o city Berlim, você poderá usar um query para retornar detalhes da variação.

Query de amostra

{
  cityList (variation: "berlin_center") {
    items {
      _path
      name
      country
      population
      categories
    }
  }
}

Resultados da amostra

{
  "data": {
    "cityList": {
      "items": [
        {
          "_path": "/content/dam/sample-content-fragments/cities/berlin",
          "name": "Berlin",
          "country": "Germany",
          "population": 3669491,
          "categories": [
            "city:capital",
            "city:emea"
          ]
        }
      ]
    }
  }
}

Query de amostra - Detalhes completos de um CEO de Empresa e funcionários

Usando a estrutura dos fragmentos aninhados, esse query retorna os detalhes completos de um CEO da empresa e de todos os seus funcionários.

Query de amostra

query {
  companyList {
    items {
      name
      ceo {
        _path
        name
        firstName
        awards {
        id
          title
        }
      }
      employees {
       name
        firstName
       awards {
         id
          title
        }
      }
    }
  }
}

Resultados da amostra

{
  "data": {
    "companyList": {
      "items": [
        {
          "name": "Apple Inc.",
          "ceo": {
            "_path": "/content/dam/sample-content-fragments/persons/steve-jobs",
            "name": "Jobs",
            "firstName": "Steve",
            "awards": []
          },
          "employees": [
            {
              "name": "Marsh",
              "firstName": "Duke",
              "awards": []
            },
            {
              "name": "Caulfield",
              "firstName": "Max",
              "awards": [
                {
                  "id": "GB",
                  "title": "Gameblitz"
                }
              ]
            }
          ]
        },
        {
          "name": "Little Pony, Inc.",
          "ceo": {
            "_path": "/content/dam/sample-content-fragments/persons/adam-smith",
            "name": "Smith",
            "firstName": "Adam",
            "awards": []
          },
          "employees": [
            {
              "name": "Croft",
              "firstName": "Lara",
              "awards": [
                {
                  "id": "GS",
                  "title": "Gamestar"
                }
              ]
            },
            {
              "name": "Slade",
              "firstName": "Cutter",
              "awards": [
                {
                  "id": "GB",
                  "title": "Gameblitz"
                },
                {
                  "id": "GS",
                  "title": "Gamestar"
                }
              ]
            }
          ]
        },
        {
          "name": "NextStep Inc.",
          "ceo": {
            "_path": "/content/dam/sample-content-fragments/persons/steve-jobs",
            "name": "Jobs",
            "firstName": "Steve",
            "awards": []
          },
          "employees": [
            {
              "name": "Smith",
              "firstName": "Joe",
              "awards": []
            },
            {
              "name": "Lincoln",
              "firstName": "Abraham",
              "awards": []
            }
          ]
        }
      ]
    }
  }
}

Query de amostra - Todas as pessoas que têm o nome "Jobs" ou "Smith"

Isso filtrará todos os persons para qualquer um que tenha o nome Jobsou Smith.

Query de amostra

query {
  personList(filter: {
    name: {
      _logOp: OR
      _expressions: [
        {
          value: "Jobs"
        },
        {
          value: "Smith"
        }
      ]
    }
  }) {
    items {
      name
      firstName
    }
  }
}

Resultados da amostra

{
  "data": {
    "personList": {
      "items": [
        {
          "name": "Smith",
          "firstName": "Adam"
        },
        {
          "name": "Smith",
          "firstName": "Joe"
        },
        {
          "name": "Jobs",
          "firstName": "Steve"
        }
      ]
    }
  }
}

Query de amostra - Todas as pessoas que não têm o nome "Jobs"

Isso filtrará todos os persons para qualquer um que tenha o nome Jobsou Smith.

Query de amostra

query {
  personList(filter: {
    name: {
      _expressions: [
        {
          value: "Jobs"
          _operator: EQUALS_NOT
        }
      ]
    }
  }) {
    items {
      name
      firstName
    }
  }
}

Resultados da amostra

{
  "data": {
    "personList": {
      "items": [
        {
          "name": "Lincoln",
          "firstName": "Abraham"
        },
        {
          "name": "Smith",
          "firstName": "Adam"
        },
        {
          "name": "Slade",
          "firstName": "Cutter"
        },
        {
          "name": "Marsh",
          "firstName": "Duke"
        },
        {
          "name": "Smith",
          "firstName": "Joe"
        },
        {
          "name": "Croft",
          "firstName": "Lara"
        },
        {
          "name": "Caulfield",
          "firstName": "Max"
        }
      ]
    }
  }
}

Query de amostra - Todas as cidades situadas na Alemanha ou na Suíça com uma população entre 400000 e 9999999

Aqui, uma combinação de campos é filtrada. Um AND (implícito) é usado para selecionar o intervalo populationenquanto um OR (explícito) é usado para selecionar as cidades necessárias.

Query de amostra

query {
  cityList(filter: {
    population: {
      _expressions: [
        {
          value: 400000
          _operator: GREATER_EQUAL
        }, {
          value: 1000000
          _operator: LOWER
        }
      ]
    },
    country: {
      _logOp: OR
      _expressions: [
        {
          value: "Germany"
        }, {
          value: "Switzerland"
        }
      ]
    }
  }) {
    items {
      name
      population
      country
    }
  }
}

Resultados da amostra

{
  "data": {
    "cityList": {
      "items": [
        {
          "name": "Stuttgart",
          "population": 634830,
          "country": "Germany"
        },
        {
          "name": "Zurich",
          "population": 415367,
          "country": "Switzerland"
        }
      ]
    }
  }
}

Query de amostra - Todas as cidades com SAN no nome, independentemente do caso

Este query interroga todas as cidades que tenham SAN no nome, independentemente do caso.

Query de amostra

query {
  cityList(filter: {
    name: {
      _expressions: [
        {
          value: "SAN"
          _operator: CONTAINS
          _ignoreCase: true
        }
      ]
    }
  }) {
    items {
      name
      population
      country
    }
  }
}

Resultados da amostra

{
  "data": {
    "cityList": {
      "items": [
        {
          "name": "San Francisco",
          "population": 883306,
          "country": "USA"
        },
        {
          "name": "San Jose",
          "population": 1026350,
          "country": "USA"
        }
      ]
    }
  }
}

Query de amostra - Filtre em uma matriz com um item que deve ocorrer pelo menos uma vez

Este query filtros em uma matriz com um item (city:na) que deve ocorrer pelo menos uma vez.

Query de amostra

query {
  cityList(filter: {
    categories: {
      _expressions: [
        {
          value: "city:na"
          _apply: AT_LEAST_ONCE
        }
      ]
    }
  }) {
    items {
      name
      population
      country
      categories
    }
  }
}

Resultados da amostra

{
  "data": {
    "cityList": {
      "items": [
        {
          "name": "San Francisco",
          "population": 883306,
          "country": "USA",
          "categories": [
            "city:beach",
            "city:na"
          ]
        },
        {
          "name": "San Jose",
          "population": 1026350,
          "country": "USA",
          "categories": [
            "city:na"
          ]
        }
      ]
    }
  }
}

Query de amostra - Filtrar em um valor de matriz exato

Este query filtros em um valor de matriz exato.

Query de amostra

query {
  cityList(filter: {
    categories: {
      _expressions: [
        {
          values: [
            "city:beach",
            "city:na"
          ]
        }
      ]
    }
  }) {
    items {
      name
      population
      country
      categories
    }
  }
}

Resultados da amostra

{
  "data": {
    "cityList": {
      "items": [
        {
          "name": "San Francisco",
          "population": 883306,
          "country": "USA",
          "categories": [
            "city:beach",
            "city:na"
          ]
        }
      ]
    }
  }
}

Query de amostra para fragmentos de conteúdo aninhados - Todas as empresas que têm pelo menos um funcionário com o nome "Smith"

Este query ilustra a filtragem de person de name "Smith", retornando informações de dois fragmentos aninhados - company e employee.

Query de amostra

query {
  companyList(filter: {
    employees: {
      _match: {
        name: {
          _expressions: [
            {
              value: "Smith"
            }
          ]
        }
      }
    }
  }) {
    items {
      name
      ceo {
        name
        firstName
      }
      employees {
        name
        firstName
      }
    }
  }
}

Resultados da amostra

{
  "data": {
    "companyList": {
      "items": [
        {
          "name": "NextStep Inc.",
          "ceo": {
            "name": "Jobs",
            "firstName": "Steve"
          },
          "employees": [
            {
              "name": "Smith",
              "firstName": "Joe"
            },
            {
              "name": "Lincoln",
              "firstName": "Abraham"
            }
          ]
        }
      ]
    }
  }
}

Query de amostra para fragmentos de conteúdo aninhados - Todas as empresas em que todos os funcionários ganharam o prêmio "Gamestar"

Este query ilustra a filtragem em três fragmentos aninhados - company, employee e award.

Query de amostra

query {
  companyList(filter: {
    employees: {
      _apply: ALL
      _match: {
        awards: {
          _match: {
            id: {
              _expressions: [
                {
                  value: "GS"
                  _operator:EQUALS
                }
              ]
            }
          }
        }
      }
    }
  }) {
    items {
      name
      ceo {
        name
        firstName
      }
      employees {
        name
        firstName
        awards {
          id
          title
        }
      }
    }
  }
}

Resultados da amostra

{
  "data": {
    "companyList": {
      "items": [
        {
          "name": "Little Pony, Inc.",
          "ceo": {
            "name": "Smith",
            "firstName": "Adam"
          },
          "employees": [
            {
              "name": "Croft",
              "firstName": "Lara",
              "awards": [
                {
                  "id": "GS",
                  "title": "Gamestar"
                }
              ]
            },
            {
              "name": "Slade",
              "firstName": "Cutter",
              "awards": [
                {
                  "id": "GB",
                  "title": "Gameblitz"
                },
                {
                  "id": "GS",
                  "title": "Gamestar"
                }
              ]
            }
          ]
        }
      ]
    }
  }
}

Query de amostra para metadados - Lista dos metadados para prêmios com o título GB

Este query ilustra a filtragem em três fragmentos aninhados - company, employee e award.

Query de amostra

query {
  awardList(filter: {
      id: {
        _expressions: [
          {
            value:"GB"
          }
        ]
    }
  }) {
    items {
      _metadata {
        stringMetadata {
          name,
          value
        }
      }
      id
      title
    }
  }
}

Resultados da amostra

{
  "data": {
    "awardList": {
      "items": [
        {
          "_metadata": {
            "stringMetadata": [
              {
                "name": "title",
                "value": "Gameblitz Award"
              },
              {
                "name": "description",
                "value": ""
              }
            ]
          },
          "id": "GB",
          "title": "Gameblitz"
        }
      ]
    }
  }
}

Query de amostra usando o projeto WKND

Esses query de amostra são baseados no projeto WKND. Isso tem:

  • Modelos de fragmento de conteúdo disponíveis em:
    http://<hostname>:<port>/libs/dam/cfm/models/console/content/models.html/conf/wknd

  • Fragmentos de conteúdo (e outro conteúdo) disponíveis em:
    http://<hostname>:<port>/assets.html/content/dam/wknd/en

OBSERVAÇÃO

Como os resultados podem ser extensos, eles não são reproduzidos aqui.

Query de amostra para todos os Fragmentos de conteúdo de um determinado modelo com as propriedades especificadas

Este query de amostra interroga:

  • para todos os fragmentos de conteúdo do tipo article
  • com as propriedades pathe author.

Query de amostra

{
  articleList {
    items {
      _path
      author
    }
  }
}

Query de amostra para metadados

Este query interroga:

  • para todos os fragmentos de conteúdo do tipo adventure
  • metadados

Query de amostra

{
  adventureList {
    items {
      _path,
      _metadata {
        stringMetadata {
          name,
          value
        }
        stringArrayMetadata {
          name,
          value
        }
        intMetadata {
          name,
          value
        }
        intArrayMetadata {
          name,
          value
        }
        floatMetadata {
          name,
          value
        }
        floatArrayMetadata {
          name,
          value
        }
        booleanMetadata {
          name,
          value
        }
        booleanArrayMetadata {
          name,
          value
        }
        calendarMetadata {
          name,
          value
        }
        calendarArrayMetadata {
          name,
          value
        }
      }
    }
  }
}

Query de amostra para um único fragmento de conteúdo de um determinado modelo

Este query de amostra interroga:

  • para um único Fragmento de conteúdo do tipo article em um caminho específico
    • dentro desse conteúdo, todos os formatos de conteúdo:
      • HTML
      • Markdown
      • Texto sem formatação
      • JSON

Query de amostra

{
  articleByPath (_path: "/content/dam/wknd/en/magazine/alaska-adventure/alaskan-adventures") {
    item {
        _path
        author
        main {
          html
          markdown
          plaintext
          json
        }
    }
  }
}

Query de amostra para um modelo de fragmento de conteúdo de um modelo

Este query de amostra interroga:

  • para um único fragmento de conteúdo
    • detalhes do Modelo de fragmento de conteúdo subjacente

Query de amostra

{
  adventureByPath(_path: "/content/dam/wknd/en/adventures/riverside-camping-australia/riverside-camping-australia") {
    item {
      _path
      adventureTitle
      _model {
        _path
        title
      }
    }
  }
}

Query de amostra para um fragmento de conteúdo aninhado - Tipo de modelo único

Este query interroga:

  • para um único Fragmento de conteúdo do tipo article em um caminho específico
    • dentro disso, o caminho e o autor do fragmento referenciado (aninhado)
OBSERVAÇÃO

O campo referencearticle tem o tipo de Dados fragment-reference.

Query de amostra

{
  articleByPath (_path: "/content/dam/wknd/en/magazine/skitouring/skitouring") {
    item {
        _path
        author
        referencearticle {
          _path
          author
      }
    }
  }
}

Query de amostra para um fragmento de conteúdo aninhado - Tipo de vários modelos

Este query interroga:

  • para vários Fragmentos de conteúdo do tipo bookmark
    • com referências de fragmento a outros fragmentos dos tipos de modelo específicos article e adventure
OBSERVAÇÃO

O campo fragments tem o tipo de Dados fragment-reference, com os modelos Article, Adventure selecionados.

{
  bookmarkList {
    items {
        fragments {
          ... on ArticleModel {
            _path
            author
          }
          ... on AdventureModel {
            _path
            adventureTitle
          }
        }
     }
  }
}

Query de amostra para um fragmento de conteúdo de um modelo específico com referências de conteúdo

Há dois sabores deste query:

  1. Para retornar todas as referências de conteúdo.
  2. Para retornar as referências de conteúdo específicas do tipo attachments.

Estes query interrogam:

  • para vários Fragmentos de conteúdo do tipo bookmark
    • com referências de conteúdo para outros fragmentos

Query de amostra para vários fragmentos de conteúdo com referências pré-definidas

O query a seguir retorna todas as referências de conteúdo usando _references:

{
  bookmarkList {
     _references {
         ... on ImageRef {
          _path
          type
          height
        }
        ... on MultimediaRef {
          _path
          type
          size
        }
        ... on DocumentRef {
          _path
          type
          author
        }
        ... on ArchiveRef {
          _path
          type
          format
        }
    }
    items {
        _path
    }
  }
}

Query de amostra para vários fragmentos de conteúdo com Anexos

O query a seguir retorna todos os attachments - um campo específico (subgrupo) do tipo content-reference:

OBSERVAÇÃO

O campo attachments tem o tipo de Dados content-reference, com vários formulários selecionados.

{
  bookmarkList {
    items {
      attachments {
        ... on PageRef {
          _path
          type
        }
        ... on ImageRef {
          _path
          width
        }
        ... on MultimediaRef {
          _path
          size
        }
        ... on DocumentRef {
          _path
          author
        }
        ... on ArchiveRef {
          _path
          format
        }
      }
    }
  }
}

Query de amostra para um único fragmento de conteúdo com referência em linha RTE

Este query interroga:

  • para um único Fragmento de conteúdo do tipo bookmark em um caminho específico
    • dentro disso, referências em linha do RTE
OBSERVAÇÃO

As referências em linha do RTE são hidratadas em _references.

Query de amostra

{
  bookmarkByPath(_path: "/content/dam/wknd/en/bookmarks/skitouring") {
    item {
      _path
      description {
        json
      }
    }
    _references {
      ... on ArticleModel {
        _path
      }
      ... on AdventureModel {
        _path
      }
      ... on ImageRef {
        _path
      }
      ... on MultimediaRef {
        _path
      }
      ... on DocumentRef {
        _path
      }
      ... on ArchiveRef {
        _path
      }
    }
  }
}

Query de amostra para uma única variação de Fragmento de conteúdo de um determinado Modelo

Este query interroga:

  • para um único Fragmento de conteúdo do tipo article em um caminho específico
    • nesse contexto, os dados relativos à variação: variation1

Query de amostra

{
  articleByPath (_path: "/content/dam/wknd/en/magazine/alaska-adventure/alaskan-adventures", variation: "variation1") {
    item {
      _path
      author
      main {
        html
        markdown
        plaintext
        json
      }
    }
  }
}

Query de amostra para uma Variação nomeada de vários Fragmentos de conteúdo de um determinado Modelo

Este query interroga:

  • para Fragmentos de conteúdo do tipo article com uma variação específica: variation1

Query de amostra

{
  articleList (variation: "variation1") {
    items {
      _path
      author
      main {
        html
        markdown
        plaintext
        json
      }
    }
  }
}

Query de amostra para vários Fragmentos de conteúdo de uma determinada localidade

Este query interroga:

  • para Fragmentos de conteúdo do tipo article na localidade fr

Query de amostra

{ 
  articleList (_locale: "fr") {
    items {
      _path
      author
      main {
        html
        markdown
        plaintext
        json
      }
    }
  }
}

A Amostra da estrutura do fragmento do conteúdo (usada com GraphQL)

Os query de amostra são baseados na seguinte estrutura, que usa:

Modelos de fragmento de conteúdo de amostra (Schemas)

Para os query de amostra, usaremos os seguintes Modelos de conteúdo e suas inter-relações (referências ->):

Empresa

Os campos básicos que definem a empresa são:

Nome do campo Tipo de dados Referência
Nome da empresa Texto em linha única
CEO Referência do fragmento (único) Person
Funcionários Referência do fragmento (vários campos) Pessoa

Person

Os campos que definem uma pessoa, que também pode ser um funcionário:

Nome do campo Tipo de dados Referência
Nome Texto em linha única
Nome Texto em linha única
Prêmios Referência do fragmento (vários campos) Prêmio

Prêmio

Os campos que definem um prêmio são:

Nome do campo Tipo de dados Referência
Atalho/ID Texto em linha única
Título Texto em linha única

Cidade

Os campos para definir uma cidade são:

Nome do campo Tipo de dados Referência
Nome Texto em linha única
País Texto em linha única
População Número
Categorias Tags

Amostra de fragmentos de conteúdo

Os seguintes fragmentos são usados para o modelo apropriado.

Empresa

Nome da empresa CEO Funcionários
Apple Steve Jobs Duke Marsh
Max Caulfield
Little Pony Inc. Adam Smith Lara Croft
Escória Cortadora
NextStep Inc. Steve Jobs Joe Smith
Abe Lincoln

Pessoa

Nome Nome Prêmios
Lincoln Abe
Smith Adam
Barra Cortador Gameblitz
Gamestar
pântano Duke
Smith Joe
Corte Lara Gamestar
Caulfield Máximo Gameblitz
Tarefas Steve

Prêmio

Atalho/ID Título
GB Gameblitz
GS Gamestar
OSC Oscar

Cidade

Nome País População Categorias
Basileia Suíça 172258 cidade:emea
Berlim Alemanha 3669491 cidade:capital
cidade:emea
Bucareste Romênia 1821000 cidade:capital
cidade:emea
São Francisco EUA 883306 cidade:praia
cidade:na
San Jose EUA 102635 cidade:na
Stuttgart Alemanha 634830 cidade:emea
Zurique Suíça 415367 cidade:capital
cidade:emea

Nesta página

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free