Skip to main content

Migrar desde Rest hacia GraphQL

Aprende las mejores prácticas y consideraciones para migrar desde la API de Rest de GitHub hacia la API de GrpahQL de GitHub.

Diferencias en la lógica de la API

GitHub proporciona dos API: una API REST y una API GraphQL. Para más información sobre las API de GitHub, consulta Comparación de la API REST de GitHub y la API de GraphQL.

Migrar desde Rest hacia GraphQL represente un cambio significativo en la lógica de las API. Las diferencias entre REST como un estilo y GraphQL como una especificación hacen difícil —y a menudo desaconsejable— reemplazar las llamadas a la API REST con las consultas de la API de GraphQL de una forma uno a uno. Hemos incluido ejemplos específicos de migración a continuación.

Para migrar el código de la API REST a la API de GraphQL:

Las ventajas significativas de GraphQL incluyen:

Aquí hay algunos ejemplos de cada una.

Ejemplo: obtener los datos que necesitas y únicamente eso

Una sola llamada de la API de REST recupera una lista de los miembros de tu organización:

curl -v https://api.github.com/orgs/:org/members

La carga útil de REST contiene datos en exceso si tu meta es recuperar únicamente los nombres y enlaces a los avatares. Sin embargo, la consulta de GraphQL recupera únicamente lo que especificas:

query {
    organization(login:"github") {
    membersWithRole(first: 100) {
      edges {
        node {
          name
          avatarUrl
        }
      }
    }
  }
}

Considera otro ejemplo: recuperar una lista de solicitudes de extracción y revisar si cada una es fusionable. Una llamada a la API REST recupera una lista de solicitudes de incorporación de cambios y sus representaciones de resumen:

curl -v https://api.github.com/repos/:owner/:repo/pulls

Para determinar si una solicitud de incorporación de cambios se puede fusionar es necesario recuperar cada solicitud individualmente de acuerdo con su representación detallada (una carga útil grande) y comprobar si su atributo mergeable es verdadero o falso:

curl -v https://api.github.com/repos/:owner/:repo/pulls/:number

Con GraphQL, solo se pueden recuperar los atributos number y mergeable para cada solicitud de incorporación de cambios:

query {
    repository(owner:"octocat", name:"Hello-World") {
    pullRequests(last: 10) {
      edges {
        node {
          number
          mergeable
        }
      }
    }
  }
}

Ejemplo: Anidar

Hacer consultas con campos anidados te permite reemplazar varios llamados de REST con menos consultas de GraphQL. Por ejemplo, para recuperar una solicitud de incorporación de cambios junto con sus confirmaciones, comentarios no revisados y revisiones mediante la API REST se necesitan cuatro llamadas independientes:

curl -v https://api.github.com/repos/:owner/:repo/pulls/:number
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number/commits
curl -v https://api.github.com/repos/:owner/:repo/issues/:number/comments
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number/reviews

Con la API de GraphQL, puede recuperar los datos con una sola consulta mediante campos anidados:

{
  repository(owner: "octocat", name: "Hello-World") {
    pullRequest(number: 1) {
      commits(first: 10) {
        edges {
          node {
            commit {
              oid
              message
            }
          }
        }
      }
      comments(first: 10) {
        edges {
          node {
            body
            author {
              login
            }
          }
        }
      }
      reviews(first: 10) {
        edges {
          node {
            state
          }
        }
      }
    }
  }
}

También puede ampliar la eficacia de esta consulta sustituyendo una variable por el número de solicitudes de incorporación de cambios.

Ejemplo: Escritura inflexible

Los modelos de GraphQL tienen una escritura inflexible, lo cual hace más seguro el manejo de los datos.

Imagínese, por ejemplo, que agrega un comentario a una incidencia o solicitud de incorporación de cambios con una mutación de GraphQL y, por error, especifica un entero en lugar de una cadena para el valor de clientMutationId:

mutation {
  addComment(input:{clientMutationId: 1234, subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
    clientMutationId
    commentEdge {
      node {
        body
        repository {
          id
          name
          nameWithOwner
        }
        issue {
          number
        }
      }
    }
  }
}

Ejecutar esta consulta recuperará errores que especificarán los tipos esperados para esta operación:

{
  "data": null,
  "errors": [
    {
      "message": "Argument 'input' on Field 'addComment' has an invalid value. Expected type 'AddCommentInput!'.",
      "locations": [
        {
          "line": 3,
          "column": 3
        }
      ]
    },
    {
      "message": "Argument 'clientMutationId' on InputObject 'AddCommentInput' has an invalid value. Expected type 'String'.",
      "locations": [
        {
          "line": 3,
          "column": 20
        }
      ]
    }
  ]
}

Al entrecomillar 1234, se transforma el valor de un entero a una cadena, el tipo esperado:

mutation {
  addComment(input:{clientMutationId: "1234", subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
    clientMutationId
    commentEdge {
      node {
        body
        repository {
          id
          name
          nameWithOwner
        }
        issue {
          number
        }
      }
    }
  }
}