Iniciar con la API de REST

Aprende las bases para utilizar la API de REST, comenzando con la autenticación y algunos ejemplos de las terminales.

Vamos a explicar los conceptos centrales de la API mientras incluímos algunos casos de uso cotidiano.

Nota: La siguiente guía utiliza la API de REST para GitHub.com.

  • Utiliza https://[hostname]/api/v3 para acceder a la API para GitHub AE.

  • La guía especifica los nombres de usuario y repositorios que podrían no existir en tu empresa. Puede que necesites utilizar nombres diferentes para ver una salida similar.

Resumen

La mayoría de las aplicaciones utilizan una biblioteca de seguridad en el lenguaje de programación que escojas, pero es importante que te familiarices con los métodos HTTP básicos de la API primero.

No hay una forma más fácil de hacerlo que a través de cURL.

Hola Mundo

Comencemos por probar nuestra configuración. Abre una instancia de la línea de comandos e ingresa el siguiente comando:

$ curl https://api.github.com/zen

> Keep it logically awesome.

La respuesta será una selección aleatoria de nuestra filosofía de diseño.

Posteriormente, vamos a hacer GET para el perfil de GitHub de Chris Wanstrath:

# GET /users/defunkt
$ curl https://api.github.com/users/defunkt

> {
>   "login": "defunkt",
>   "id": 2,
>   "node_id": "MDQ6VXNlcjI=",
>   "avatar_url": "https://avatars.githubusercontent.com/u/2?v=4",
>   "gravatar_id": "",
>   "url": "https://api.github.com/users/defunkt",
>   "html_url": "https://github.com/defunkt",
>   ...
> }

Mmmm, sabe a JSON. Vamos a agregar el marcador -i para que incluya los encabezados:

$ curl -i https://api.github.com/users/defunkt

> HTTP/2 200 
> server: GitHub.com
> date: Thu, 08 Jul 2021 07:04:08 GMT
> content-type: application/json; charset=utf-8
> cache-control: public, max-age=60, s-maxage=60
> vary: Accept, Accept-Encoding, Accept, X-Requested-With
> etag: W/"61e964bf6efa3bc3f9e8549e56d4db6e0911d8fa20fcd8ab9d88f13d513f26f0"
> last-modified: Fri, 01 Nov 2019 21:56:00 GMT
> x-github-media-type: github.v3; format=json
> access-control-expose-headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset
> access-control-allow-origin: *
> strict-transport-security: max-age=31536000; includeSubdomains; preload
> x-frame-options: deny
> x-content-type-options: nosniff
> x-xss-protection: 0
> referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin
> content-security-policy: default-src 'none'
> x-ratelimit-limit: 60
> x-ratelimit-remaining: 53
> x-ratelimit-reset: 1625731053
> x-ratelimit-resource: core
> x-ratelimit-used: 7
> accept-ranges: bytes
> content-length: 1305
> x-github-request-id: 9F60:7019:ACC5CD5:B03C931:60E6A368
>
> {
>  "login": "defunkt",
>  "id": 2,
>  "node_id": "MDQ6VXNlcjI=",
>  "avatar_url": "https://avatars.githubusercontent.com/u/2?v=4",
>  "gravatar_id": "",
>  "url": "https://api.github.com/users/defunkt",
>  "html_url": "https://github.com/defunkt",
>
>   ...
> }

Hay algunas partes interesantes en los encabezados de la respuesta. Como lo esperábamos, el Content-Type es application/json.

Cualquier encabezado que comience como X se refiere a un encabezado personalizado, y no se incluirá en la especificación de HTTPS. Por ejemplo:

  • X-GitHub-Media-Type tiene un valor de github.v3. Esto nos permite saber el tipo de medios para la respuesta. Los tipos de medios nos han ayudado a versionar nuestra salida en la API v3. Hablaremos más sobre esto después.
  • Toma nota de los encabezados X-RateLimit-Limit y X-RateLimit-Remaining. Este par de encabezados indica cuántas solicitudes puede hacer un cliente en un periodo de tiempo consecutivo (habitualmente una hora) y cuántas de estas solicitudes ha gastado el cliente hasta ahora.

Autenticación

Los clientes sin autenticar pueden hacer hasta 60 solicitudes por hora. Para obtener más solicitudes por hora, necesitaremos autenticarnos. De hecho, necesitaremos la autenticación para hacer cualquier cosa interesante con la API de GitHub AE.

Utilizar tokens de acceso personal

La mejor y más fácil forma de autenticarse con la API de GitHub AE es utilizando la Autenticación Básica a través de los tokens de OAuth. Éstos incluyen tokens de acceso personal.

Utiliza el marcador -u para configurar tu nombre de usuario:

$ curl -i -u your_username https://[hostname]/api/v3/users/octocat

Cuando se te solicite, puedes ingresar tu token de OAuth, pero te recomendamos que configures una variable para éste:

Puedes utilizar -u "your_username:$token" y configurar una variable para token y así evitar que tu token se quede en el historial del shell, lo cual debes evitar.

$ curl -i -u your_username:$token https://[hostname]/api/v3/users/octocat

Cuando te autentiques, debes ver como tu límite de tasa sube hasta 5,000 solicitudes por hora, como se indicó en el encabezado X-RateLimit-Limit. Adicionalmente a proporcionar más llamadas por hora, la autenticación te permite leer y escribir información privada utilizando la API.

Puedes crear untoken de acceso personal fácilmente utilizando tu página de configuración para tokens de acceso personal:

Selección de token personal

Obtén tu propio perfil de usuario

Cuando te autenticas adecuadamente, puedes sacar provecho de los permisos asociados con tu cuenta de GitHub AE. Por ejemplo, intenta obtener

$ curl -i -u your_username:your_token https://[hostname]/api/v3/user

> {
>   ...
>   "plan": {
>     "space": 2516582,
>    "collaborators": 10,
>    "private_repos": 20,
>    "name": "medium"
>  }
>   ...
> }

Esta vez, adicionalmente al mismo conjunto de información pública que recuperamos para @defunkt anteriormente, también deberías ver la información diferente a la pública para tu perfil de usuario. Por ejemplo, verás un objeto de plan en la respuesta, el cual otorga detalles sobre el plan de GitHub AE que tiene la cuenta.

Utiilzar tokens de OAuth para las apps

Las apps que necesitan leer o escribir información privada utilizando la API en nombre de otro usuario deben utilizar OAuth.

OAuth utiliza tokens. Los Tokens proporcionan dos características grandes:

  • Acceso revocable: los usuarios pueden revocar la autorización a las apps de terceros en cualquier momento
  • Acceso limitado: los usuarios pueden revisar el acceso específico que proporcionará un token antes de autorizar una app de terceros

Los tokens deben crearse mediante un flujo web. Una aplicación envía a los usuarios a GitHub AE para que inicien sesión. Entonces, GitHub AE presenta un diálogo que indica el nombre de la app así como el nivel de acceso que ésta tiene una vez que el usuario la autorice. Después de que un usuario autoriza el acceso, GitHub AE lo redirecciona de vuelta a la aplicación:

Diálogo de OAuth de GitHub

¡Trata a los tokens de OAuth como si fueran contraseñas! No los compartas con otros usuarios ni los almacenes en lugares inseguros. Los tokens en estos ejemplos son falsos y los nombres se cambiaron para proteger a los inocentes.

Ahora que ya entendimos cómo hacer llamadas autenticadas, vamos a pasar a la API de repositorios.

Repositorios

Casi cualquier uso significativo de la API de GitHub AE involucra algún nivel de información de un repositorio. Podemos hacer GET para los detalles de un repositorio de la misma forma que recuperamos los detalles del usuario anteriormente:

$ curl -i https://[hostname]/api/v3/repos/twbs/bootstrap

De la misma forma, podemos ver los repositorios del usuario autenticado:

$ curl -i -H "Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4" \
    https://[hostname]/api/v3/user/repos

O podemos listar los repositorios de otro usuario:

$ curl -i https://[hostname]/api/v3/users/octocat/repos

O podemos listar los repositorios de una organización:

$ curl -i https://[hostname]/api/v3/orgs/octo-org/repos

La información que se devuelve de estas llamadas dependerá de los alcances que tenga nuestrotoken cuando nos autenticamos:

  • Un token con alcance de repo devolverá una respuesta que incluya todos los repositorios internos y privados que podemos ver en tu empresa.

Como indican los docs, estos métodos toman un parámetro de type que puede filtrar los repositorios que se regresan con base en el tipo de acceso que el usuario tiene en ellos. De esta forma, podemos obtener los solo los repositorios que nos pertenezcan directamente, repositorios de organizacion o repositorios en los que el usuario colabore a través del equipo.

$ curl -i "https://[hostname]/api/v3/users/octocat/repos?type=owner"

En este ejemplo, tomamos únicamente los repositorios que pertenecen a octocat, no aquellos en los que ella colabora. Nota la URL que se cita arriba. Dependiendo de tu configuración de shell, cURL a veces requiere una URL citada, o de lo contrario ignora la secuencia de consulta.

Crear un repositorio

Un caso de común de uso es retribuir información para repositorios existentes, pero la API de GitHub AE es compatible con la creación de repositorios nuevos también. Para crear un repositorio, necesitamos hacer POST en algunos JSON que contengan los detalles y las opciones de configuración.

$ curl -i -H "Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4" \
    -d '{ \
        "name": "blog", \
        "auto_init": true, \
        "private": true, \
        "gitignore_template": "nanoc" \
      }' \
    https://[hostname]/api/v3/user/repos

En este ejemplo mínimo, creamos un repositorio privado nuevo para nuestro blog (que se servirá en GitHub Pages, probablemente). Aunque el blog está disponible para todos los miembros de la empresa, hemos hecho el repositorio privado. En este paso, también lo inicializaremos con un README y con una plantilla de.gitignored enriquecida con nanoc.

El repositorio que se obtiene como resultado se puede encontrar en https://github.com/<your_username>/blog. Para crear un repositorio bajo una organización para la cual eres propietario, solo cambia el método de la API de /user/repos a /orgs/<org_name>/repos.

Posteriormente vamos a obtener nuestro repositorio recién creado:

$ curl -i https://[hostname]/api/v3/repos/pengwynn/blog

> HTTP/2 404

> {
>    "message": "Not Found"
> }

¡Oh no! ¿A dónde se fue? Ya que creamos el repositorio como privado, necesitamos autenticarnos para poder verlo. Si eres un usuario experimentado en HTTP, tal vez esperes recibir un código 403 en vez de ésto. Ya que no queremos filtrar información acerca de los repositorios privados, la API de GitHub AE devuelve un código 404 en este caso, como diciendo "no podemos confirmar ni negar la existencia de este repositorio".

Problemas

La IU de informe de problemas en GitHub AE pretende proporcionar suficiente flujo de trabajo mientras evita estorbarte. Con la API de propuestas de GitHub AE, puedes extraer datos para crear propuestas desde otras herramientas para crear flujos de trabajo que funcionen para tu equipo.

Tal como en github.com, la API proporciona algunos cuantos métodos para ver los informes de problemas para el usuario autenticado. Para ver todas tus propuestas, llama a GET /issues:

$ curl -i -H "Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4" \
    https://[hostname]/api/v3/issues

Para obtener únicamente las propuestas bajo alguna de tus organizaciones de GitHub AE, llama a GET /orgs/<org>/issues:

$ curl -i -H "Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4" \
    https://[hostname]/api/v3/orgs/rails/issues

También podemos obtener todas las propuestas que estén bajo un solo repositorio:

$ curl -i https://[hostname]/api/v3/repos/rails/rails/issues

Paginación

Un proyecto con el tamaño de Rails tiene miles de informes de problemas. Necesitaremos paginar, haciendo varias llamadas a la API para obtener los datos. Vamos a repetir la última llamada, esta vez tomando nota de los encabezados de respuesta:

$ curl -i https://[hostname]/api/v3/repos/rails/rails/issues

> HTTP/2 200

> ...
> Link: <https://[hostname]/api/v3/repositories/8514/issues?page=2>; rel="next", <https://[hostname]/api/v3/repositories/8514/issues?page=30>; rel="last"
> ...

El encabezado de Link proporciona una respuesta para enlazar a los recursos externos, en este caso, a las páginas de datos adicionales. Ya que nuestra llamada encontró más de treinta informes de problemas (el tamaño predeterminado de página), la API no s dice dónde podemos encontrar la siguiente página y la última página de los resultados.

Crear una propuesta

Ahora que hemos visto cómo paginar las listas de propuestas, vamos a crear una propuesta desde la API.

Para crear un informe de problemas, necesitamos estar autenticados, así que pasaremos un token de OAuth en el encabezado. También, pasaremos el título, cuerpo, y etiquetas en el cuerpo de JSON a la ruta /issues debajo del repositorio en el cual queremos crear el informe de problemas:

$ curl -i -H 'Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4' \
$    -d '{ \
$         "title": "New logo", \
$         "body": "We should have one", \
$         "labels": ["design"] \
$       }' \
$    https://[hostname]/api/v3/repos/pengwynn/api-sandbox/issues

> HTTP/2 201
> Location: https://[hostname]/api/v3/repos/pengwynn/api-sandbox/issues/17
> X-RateLimit-Limit: 5000

> {
>   "pull_request": {
>     "patch_url": null,
>     "html_url": null,
>     "diff_url": null
>   },
>   "created_at": "2012-11-14T15:25:33Z",
>   "comments": 0,
>   "milestone": null,
>   "title": "New logo",
>   "body": "We should have one",
>   "user": {
>     "login": "pengwynn",
>     "gravatar_id": "7e19cd5486b5d6dc1ef90e671ba52ae0",
>     "avatar_url": "https://secure.gravatar.com/avatar/7e19cd5486b5d6dc1ef90e671ba52ae0?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png",
>     "id": 865,
>     "url": "https://[hostname]/api/v3/users/pengwynn"
>   },
>   "closed_at": null,
>   "updated_at": "2012-11-14T15:25:33Z",
>   "number": 17,
>   "closed_by": null,
>   "html_url": "https://github.com/pengwynn/api-sandbox/issues/17",
>   "labels": [
>     {
>       "color": "ededed",
>       "name": "design",
>       "url": "https://[hostname]/api/v3/repos/pengwynn/api-sandbox/labels/design"
>     }
>   ],
>   "id": 8356941,
>   "assignee": null,
>   "state": "open",
>   "url": "https://[hostname]/api/v3/repos/pengwynn/api-sandbox/issues/17"
> }

La respuesta nos entrega un par de sugerencias para el informe de problemas recién creado, tanto en el encabezado de respuesta de Location como en el campo de url de la respuesta de JSON.

Solicitudes condicionales

Una gran parte de ser un buen ciudadano de la API es respetar los límites de tasa al almacenar información en el caché, la cual no haya cambiado. La API es compatible con las solicitudes condicionales y te ayuda a hacer lo correcto. Considera el primer llamado que hicimos para obtener el perfil de defunkt:

$ curl -i https://[hostname]/api/v3/users/defunkt

> HTTP/2 200
> etag: W/"61e964bf6efa3bc3f9e8549e56d4db6e0911d8fa20fcd8ab9d88f13d513f26f0"

Además del cuerpo de JSON, toma nota del código de estado HTTP de 200 y del encabezado ETag. La ETag es una huella digital de la respuesta. Si la pasamos en llamadas subsecuentes, podemos decirle a la API que nos entregue el recurso nuevamente, únicamente si cambió:

$ curl -i -H 'If-None-Match: "61e964bf6efa3bc3f9e8549e56d4db6e0911d8fa20fcd8ab9d88f13d513f26f0"' \
$    https://[hostname]/api/v3/users/defunkt

> HTTP/2 304

El estado 304 indica que el recurso no ha cambiado desde la última vez que lo solicitamos y que la respuesta no contendrá ningún cuerpo. Como bonificación, las respuestas 304 no contarán para tu límite de tasa.

¡Qué! ¡Ahora sabes los fundamentos de la API de GitHub AE!

  • Autenticación básica & de OAuth
  • Obtener y crear repositorios e informes de problemas
  • Solicitudes condicionales

Sigue aprendiendo con la siguiente guía de la API ¡Fundamentos de la Autenticación!

¿Te ayudó este documento?

Política de privacidad

¡Ayúdanos a hacer geniales estos documentos!

Todos los documentos de GitHub son de código abierto. ¿Notas algo que esté mal o que no sea claro? Emite una solicitud de cambios.

Haz una contribución

O, aprende cómo contribuir.