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
http(s)://[hostname]/api/v3
para acceder a la API para GitHub Enterprise Server. -
La guía especifica los nombres de usuario y repositorios que podrían no existir en tu instancia de GitHub Enterprise Server. 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 degithub.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
yX-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 Enterprise Server.
Utilizar tokens de acceso personal
La mejor y más fácil forma de autenticarse con la API de GitHub Enterprise Server 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 http(s)://[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 http(s)://[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:
Obtén tu propio perfil de usuario
Cuando te autenticas adecuadamente, puedes sacar provecho de los permisos asociados con tu cuenta de GitHub Enterprise Server. Por ejemplo, intenta obtener
$ curl -i -u your_username:your_token http(s)://[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 Enterprise Server 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 Enterprise Server para que inicien sesión. Entonces, GitHub Enterprise Server 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 Enterprise Server lo redirecciona de vuelta a la aplicación:
¡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 Enterprise Server 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 http(s)://[hostname]/api/v3/repos/twbs/bootstrap
De la misma forma, podemos ver los repositorios del usuario autenticado:
$ curl -i -H "Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4" \
http(s)://[hostname]/api/v3/user/repos
O podemos listar los repositorios de otro usuario:
$ curl -i http(s)://[hostname]/api/v3/users/octocat/repos
O podemos listar los repositorios de una organización:
$ curl -i http(s)://[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
public_repo
devolverá una respuesta que incluye todos los repositorios públicos que podemos ver en github.com. - Un token con alcance de
repo
devolverá una respuesta que incluya todos los repositorios públicos y privados que podemos ver en tu instancia de GitHub Enterprise Server.
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 "http(s)://[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 Enterprise Server 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" \
}' \
http(s)://[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 será público, 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 http(s)://[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 Enterprise Server 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 Enterprise Server pretende proporcionar suficiente flujo de trabajo mientras evita estorbarte. Con la API de propuestas de GitHub Enterprise Server, 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" \
http(s)://[hostname]/api/v3/issues
Para obtener únicamente las propuestas bajo alguna de tus organizaciones de GitHub Enterprise Server, llama a GET /orgs/<org>/issues
:
$ curl -i -H "Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4" \
http(s)://[hostname]/api/v3/orgs/rails/issues
También podemos obtener todas las propuestas que estén bajo un solo repositorio:
$ curl -i http(s)://[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 http(s)://[hostname]/api/v3/repos/rails/rails/issues
> HTTP/2 200
> ...
> Link: <http(s)://[hostname]/api/v3/repositories/8514/issues?page=2>; rel="next", <http(s)://[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"] \
$ }' \
$ http(s)://[hostname]/api/v3/repos/pengwynn/api-sandbox/issues
> HTTP/2 201
> Location: http(s)://[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": "http(s)://[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": "http(s)://[hostname]/api/v3/repos/pengwynn/api-sandbox/labels/design"
> }
> ],
> "id": 8356941,
> "assignee": null,
> "state": "open",
> "url": "http(s)://[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 http(s)://[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"' \
$ http(s)://[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 Enterprise Server!
- 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!