Blog

🥳 Gato GraphQL v0.9 foi lançado!

Leonardo Losoviz
Por Leonardo Losoviz ·

Após quase 1,5 anos de desenvolvimento e mais de 16.000 commits, uma nova versão do Gato GraphQL foi finalmente lançada! 🥳

A versão 0.9 é o maior lançamento na história do plugin. Aqui está o changelog, e aqui está o detalhamento completo de todas as novas funcionalidades:

github.com/GatoGraphQL/GatoGraphQL/releases/tag/0.9.3

Este documento é bem longo (mais de 40 min de leitura!), então abaixo segue um TL;DR com as mudanças mais importantes.

Schema GraphQL significativamente ampliado

O modelo de dados do WordPress foi significativamente mapeado no schema GraphQL.

Schema GraphQL

Entre outras melhorias, o schema conta com as seguintes:

  • Consultar dados de qualquer CPT, incluindo de qualquer tema e plugin
  • Taxonomias personalizadas mapeadas (tags e categorias)
  • Tipos GraphQL mais adequados criados e retornados (ex: HTML, URL, DateTime)
  • Argumentos de campo organizados via input objects
  • Uso de oneof input objects para selecionar uma entidade por diferentes propriedades (ex: id, slug)
  • Retornar payloads de mutations
  • Consultar configurações (de wp_options) e valores meta (para posts, usuários, comentários e taxonomias)

Custom scalars

O suporte para tipos escalares personalizados foi adicionado ao servidor GraphQL. Custom scalars permitem que você represente melhor seus dados, seja para receber uma entrada via argumento de campo, seja para imprimir uma saída personalizada na resposta.

Vários tipos escalares personalizados padrão foram implementados e já estão disponíveis para uso no seu schema GraphQL:

  • Date
  • DateTime
  • Email
  • HTML
  • URL
  • URLAbsolutePath

Custom enums

Os tipos enum personalizados agora são suportados. Enums são um tipo especial de escalar restrito a um conjunto específico de valores permitidos. Isso permite que você:

  • Valide que qualquer argumento desse tipo seja um dos valores permitidos
  • Comunique por meio do sistema de tipos que um campo sempre será um de um conjunto finito de valores

Vários tipos enum foram implementados e utilizados onde apropriado no schema GraphQL, incluindo:

  • CommentOrderByEnum
  • CommentStatusEnum
  • CommentTypeEnum
  • CustomPostOrderByEnum
  • CustomPostStatusEnum
  • MediaItemOrderByEnum
  • MenuOrderByEnum
  • TaxonomyOrderByEnum
  • UserOrderByEnum

Input Objects

O servidor GraphQL agora também suporta input types, e você pode adicionar seus próprios input objects ao schema GraphQL. Input objects permitem que você passe objetos complexos como entradas para campos, o que é particularmente útil para mutations.

Vários input objects foram adicionados onde apropriado no schema. Por exemplo, campos para consultar dados (como posts, users, comments, etc.) recebem input objects complexos nos argumentos de campo filter, sort e pagination, e campos que mutam dados (como createPost, addCommentToCustomPost, etc.) recebem um input object no argumento de campo input.

Oneof Input Objects

O "oneof" input object é um tipo especial de input object em que exatamente um dos campos de entrada deve ser fornecido como entrada; caso contrário, retorna um erro de validação. Esse comportamento introduz polimorfismo para entradas.

Por exemplo, o campo Root.post agora recebe um argumento de campo by, que é um oneof input object que permite recuperar o post por diferentes propriedades, como por id ou por slug:

{
  postByID: post(by: {
    id: 1
  }) {
    id
    title
  }
 
  postBySlug: post(by: {
    slug: "hello-world"
  }) {
    id
    title
  }
}

A vantagem é que um único campo pode ser usado para tratar diferentes casos de uso, evitando a criação de um campo diferente para cada caso (como postByID, postBySlug, etc.), tornando o schema GraphQL mais enxuto e elegante.

Vários Oneof Input Objects foram implementados:

  • Root.customPost(by:)
  • Root.mediaItem(by:)
  • Root.menu(by:)
  • Root.page(by:)
  • Root.postCategory(by:)
  • Root.postTag(by:)
  • Root.post(by:)
  • Root.user(by:)

Operation Directives

As operações GraphQL (ou seja, as operações query e mutation) agora também podem receber directives.

Restringir directives a tipos específicos

As directives (de campo) podem ser restritas para serem aplicadas somente em campos de alguns tipos específicos. Por exemplo, uma directive @strUpperCase que transforma o valor do campo em letras maiúsculas faz sentido apenas em campos String, não em Int, Float ou Boolean. Essa restrição pode agora ser declarada no directive resolver.

Exibir o caminho completo até o nó da query GraphQL que produz erros

A resposta agora contém o caminho completo até os nós na query GraphQL que retornam um erro (sob a entrada extensions.path), facilitando a identificação da origem do problema.

Por exemplo, na query abaixo, a directive @nonExisting não existe:

query {
  myField @nonExisting
}

A resposta é a seguinte:

{
  "errors": [
    {
      "message": "There is no directive with name 'nonExisting'",
      "locations": [
        {
          "line": 2,
          "column": 7
        }
      ],
      "extensions": {
        "type": "QueryRoot",
        "field": "myField @nonExisting",
        "path": [
          "@nonExisting",
          "myField @nonExisting",
          "query { ... }"
        ],
        "code": "PoP\\ComponentModel\\e20"
      }
    }
  ],
  "data": {
    "id": "root"
  }
}

Habilitar configurações padrão inseguras

O Gato GraphQL fornece configurações padrão seguras:

  • O endpoint único está desabilitado
  • Os elementos de dados "sensíveis" no schema GraphQL (como User.roles, ou filtrar posts por status) não são expostos
  • Apenas um conjunto limitado de opções de configuração e meta keys (para posts, usuários, etc.) pode ser consultado
  • O número de entidades que podem ser consultadas de uma vez é limitado (para posts, usuários, etc.)

Essas configurações padrão seguras são necessárias para manter sites "ao vivo" seguros e prevenir ataques maliciosos. No entanto, não são necessárias ao construir sites "estáticos", onde o site WordPress não está vulnerável a ataques (como quando é um site de desenvolvimento em um laptop, atrás de um firewall seguro, ou não exposto à Internet em geral).

A partir da v0.9, podemos habilitar os padrões inseguros adicionando em wp-config.php:

define( 'GRAPHQL_API_ENABLE_UNSAFE_DEFAULTS', true );

Como alternativa, podemos definir essa mesma chave/valor como uma variável de ambiente.

Ao habilitar os padrões inseguros, as configurações padrão do plugin são transformadas da seguinte forma:

  • O endpoint único é habilitado
  • Os elementos de dados "sensíveis" são expostos no schema GraphQL
  • Todas as opções de configuração e meta keys podem ser consultadas
  • O número de entidades que podem ser consultadas de uma vez é ilimitado

Organizar Custom Endpoints e Persisted Queries por categoria

Ao criar um Custom Endpoint ou uma Persisted Query, podemos adicionar uma "GraphQL endpoint category" para organizar todos os nossos endpoints:

Categorias de endpoint ao editar um Custom Endpoint

Por exemplo, podemos criar categorias para gerenciar endpoints por cliente, aplicação ou qualquer outra informação necessária:

Lista de categorias de endpoint

Na lista de Custom Endpoints e Persisted Queries, podemos visualizar suas categorias e, ao clicar em qualquer link de categoria ou usar o filtro no topo, serão exibidas apenas as entradas daquela categoria.

Lista de Custom Endpoints com suas categorias

Consultar schema extensions via introspecção

Metadados personalizados associados a elementos do schema podem agora ser consultados via campo extensions.

Todos os elementos de introspecção do schema foram atualizados com o novo campo, cada um retornando um objeto de um tipo correspondente "Extensions", que expõe as propriedades personalizadas para aquele elemento.

# Using "_" instead of "__" in introspection type name to avoid errors in graphql-js
type _SchemaExtensions {
  # Is the schema being namespaced?
  isNamespaced: Boolean!
}
 
extend type __Schema {
  extensions: _SchemaExtensions!
}
 
type _NamedTypeExtensions {
  # The type name
  elementName: String!
 
  # The "namespaced" type name
  namespacedName: String!
 
  # Enum-like "possible values" for EnumString type resolvers, `null` otherwise
  possibleValues: [String!]
 
  # OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null, all others being omitted.
  isOneOf: Boolean!
}
 
extend type __Type {
  # Non-null for named types, null for wrapping types (Non-Null and List)
  extensions: _NamedTypeExtensions
}
 
type _DirectiveExtensions {
  # If no objects are returned in the field (eg: because they failed validation), does the directive still need to be executed?
  needsDataToExecute: Boolean!
 
  # Names or descriptions of the types the field directives is restricted to, or `null` if it supports any type (i.e. it defines no restrictions)
  fieldDirectiveSupportedTypeNamesOrDescriptions: [String!]
}
 
extend type __Directive {
  extensions: _DirectiveExtensions!
}
 
type _FieldExtensions {
  isGlobal: Boolean!
 
  # Useful for nested mutations
  isMutation: Boolean!
 
  # `true` => Only exposed when "Expose "sensitive" data elements" is enabled
  isSensitiveDataElement: Boolean!
}
 
extend type __Field {
  extensions: _FieldExtensions!
}
 
type _InputValueExtensions {
  isSensitiveDataElement: Boolean!
}
 
extend type __InputValue {
  extensions: _InputValueExtensions!
}
 
type _EnumValueExtensions {
  isSensitiveDataElement: Boolean!
}
 
extend type __EnumValue {
  extensions: _EnumValueExtensions!
}

Concluído o desacoplamento do código do servidor GraphQL do WordPress

O servidor GraphQL subjacente que alimenta o plugin pode agora ser instalado e executado como um componente PHP independente, ou seja, independentemente do WordPress.

Isso abre as portas para o uso do Gato GraphQL com outros frameworks (ex: Laravel), e em qualquer ambiente PHP, com ou sem WordPress disponível (como ao executar uma tarefa de Integração Contínua).

Todos os blocos exibidos ao editar uma Schema Configuration, Custom Endpoint e Persisted Query agora têm um botão "info" que, ao ser clicado, exibe a documentação em uma janela modal.

Clicando em um botão 'info'...

...abre uma janela modal com a documentação

Muito mais

Para descobrir todas as outras novas funcionalidades, consulte a descrição completa do novo lançamento, ou navegue pelo changelog.

E baixe o plugin aqui.

Se você gostou do que viu, ajude a espalhar o amor ❤️


Assine nossa newsletter

Fique por dentro de todas as atualizações do Gato GraphQL.