Vamos a explicar los conceptos centrales de la API mientras incluímos algunos casos de uso cotidiano.
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 http(s)://[hostname]/api/v3/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 http(s)://[hostname]/api/v3/users/defunkt
> {
> "login": "defunkt",
> "id": 2,
> "url": "http(s)://[hostname]/api/v3/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 http(s)://[hostname]/api/v3/users/defunkt
> HTTP/1.1 200 OK
> Server: GitHub.com
> Date: Sun, 11 Nov 2012 18:43:28 GMT
> Content-Type: application/json; charset=utf-8
> Connection: keep-alive
> ETag: "bfd85cbf23ac0b0c8a29bee02e7117c6"
> X-RateLimit-Limit: 60
> X-RateLimit-Remaining: 57
> X-RateLimit-Reset: 1352660008
> X-GitHub-Media-Type: github.v3
> Vary: Accept
> Cache-Control: public, max-age=60, s-maxage=60
> X-Content-Type-Options: nosniff
> Content-Length: 692
> Last-Modified: Tue, 30 Oct 2012 18:58:42 GMT
> {
> "login": "defunkt",
> "id": 2,
> "url": "http(s)://[hostname]/api/v3/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.
Utilizar tokens de acceso personal
La mejor y más fácil forma de autenticarse con la API de GitHub Enterprise 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 "username:$token"
y configurar una variable para token
y así evitar el dejar tu token en el historial del shell, lo cual debe evitarse.
$ curl -i -u 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. 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 antes para @defunkt, deberías ver también la información no pública para tu perfil de usuario. Por ejemplo, verás un objeto de plan
en la respuesta, el cuál proporciona detalles sobre el plan de GitHub Enterprise de 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 para que inicien sesión. Entonces, GitHub Enterprise 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 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 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 el alcance de
public_repo
devolverá una respuesta que incluya todos los repositorios públicos a los cuales tenemos acceso de visualización en github.com. - Un token con scope de
repo
devuelve una respuesta que incluye a todos los repositorios públicos y privados a los que tenemos acceso para ver en github.com.
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
El obtener información para los repositorios existentes es un caso de uso común, pero la API de GitHub Enterprise también puede crear repositorios nuevos. Para crear un repositorio, necesitamos hacer POST
a algún JSON que contenga 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 nuevo para nuestro blog (que se servirá en GitHub Pages, probablemente). Aunque el blog será público, lo hemos hecho privado. En este paso único, también lo inicializamos con un README y con una plantilla de.gitignore aderezada 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/1.1 404 Not Found
> {
> "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 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 pretende proporcionar suficiente flujo de trabajo mientras evita estorbarte. Con la API de Informes de Problemas de GitHub Enterprise, puedes extraer datos para crear informes de problemas desde otras herramientas para crear flujos de trabajo que funcionan 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 todos tus informes de problemas, llama a GET /issues
:
$ curl -i -H "Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4" \
http(s)://[hostname]/api/v3/issues
Para obtener únicamente los informes de problemas bajo alguna de tus organizaciones de GitHub Enterprise, llama a GET /orgs/<org>/issues
:
$ curl -i -H "Authorization: token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4" \
http(s)://[hostname]/api/v3/orgs/rails/issues
También podemos obtener todos los informes de problemas 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/1.1 200 OK
> ...
> 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 code>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 informes de problemas, vamos a crear un informe de problemas 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/1.1 201 Created
> 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/1.1 200 OK
> ETag: "bfd85cbf23ac0b0c8a29bee02e7117c6"
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: "bfd85cbf23ac0b0c8a29bee02e7117c6"' \
$ http(s)://[hostname]/api/v3/users/defunkt
> HTTP/1.1 304 Not Modified
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!
- 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!