Open Source
Documentación API (GraphQL) – Historia del Internet
Una guía para acceder a los datos del proyecto “Historia del Internet” usando GraphQL
Introducción
Este proyecto almacena información sobre la historia del internet en Colombia en una base de datos de WordPress con capacidades GraphQL. Si deseas usar nuestros datos para tus propias investigaciones, esta guía te mostrará cómo hacerlo de forma sencilla.
¿Qué es GraphQL?
GraphQL es un lenguaje para pedir datos de una API. A diferencia de las APIs tradicionales que devuelven datos fijos, con GraphQL tú eliges exactamente qué datos necesitas.
¿Cómo acceder?
URL base: https://historiasinternetpre.uniandes.edu.co/graphql
Método: POST (envías datos al servidor)
Formato: JSON
Primeros pasos
Ejemplo básico con curl (terminal)
curl -X POST https://historiasinternetpre.uniandes.edu.co/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "{ pages { nodes { title slug } } }"
}'
Con JavaScript/Node.js
async function obtenerDatos(query) {
const respuesta = await fetch(
'https://historiasinternetpre.uniandes.edu.co/graphql',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
}
);
const data = await respuesta.json();
return data;
}
// Usar la función
const query = `{
pages {
nodes {
title
slug
}
}
}`;
obtenerDatos(query).then(resultado => console.log(resultado));
Con Python
import requests
import json
API_URL = "https://historiasinternetpre.uniandes.edu.co/graphql"
def obtener_datos(query):
respuesta = requests.post(
API_URL,
json={"query": query}
)
return respuesta.json()
# Usar la función
query = """
{
pages {
nodes {
title
slug
}
}
}
"""
resultado = obtener_datos(query)
print(json.dumps(resultado, indent=2))
Tipos de datos principales
El proyecto tiene varios tipos de contenido que puedes consultar:
| Tipo | Descripción | Ejemplo |
pages | Páginas estáticas del sitio | Inicio, Acerca de, Investigación |
eventos | Eventos históricos del internet | Nacimiento de ARPANET, primer .co |
documentos | Documentos, artículos, referencias | PDFs, textos académicos |
personajes | Personas importantes en la historia | Fundadores, investigadores |
entrevistas | Entrevistas a personajes | Transcripciones de entrevistas |
terminos | Términos del glosario | Definiciones técnicas |
Consultas por tipo de datos
1. PÁGINAS (Pages)
Las páginas son contenido estático del sitio web.
Campos disponibles:
title– Título de la páginaslug– URL amigable de la páginacontent– Contenido HTML de la páginadescripcion– Descripción cortamenuOrder– Orden en el menú
Consulta para obtener todas las páginas:
{
pages {
nodes {
title
slug
content
descripcion
menuOrder
}
}
}
Consulta para obtener una página específica:
{
page(id: "inicio", idType: URI) {
title
slug
content
descripcion
}
}
Nota: Algunos slugs útiles: inicio, acerca-de, documentos, glosario
2. EVENTOS (Eventos)
Los eventos son momentos importantes en la historia del internet.
Campos disponibles:
title– Nombre del eventoslug– URL amigablefecha– Fecha del evento (formato: YYYY-MM-DD)tipo– Tipo:colombiaotecnologicocontent– Descripción del eventocategories– Categorías asociadasstatus– Estado:publish,draft, etc.
Consulta para obtener eventos:
{
eventos(first: 100) {
pageInfo {
hasNextPage
endCursor
}
nodes {
title
slug
fecha
tipo
content
categories {
nodes {
name
slug
}
}
}
}
}
Consulta con paginación (obtener siguientes 100):
{
eventos(first: 100, after: "CURSOR_ANTERIOR") {
pageInfo {
hasNextPage
endCursor
}
nodes {
title
fecha
tipo
}
}
}
Tipos de eventos:
tecnologico– Hitos tecnológicos mundialescolombia– Eventos importantes en Colombia
3. DOCUMENTOS (Documentos)
Documentos, artículos y referencias del proyecto.
Campos disponibles:
title– Título del documentoslug– URL amigabletituloCorto– Título abreviadodescripcion– Resumen del documentofecha– Fecha del documentoautores– Quién escribiófuente– Dónde se obtuvoidentificador– ID únicoarchivos– Archivos adjuntostiposDeDocumentos– Clasificación (artículo, libro, etc.)categories– Temas relacionadosfeaturedImage– Imagen de portada
Consulta para obtener documentos:
{
documentos(first: 50) {
pageInfo {
hasNextPage
endCursor
}
nodes {
title
slug
tituloCorto
descripcion
fecha
autores
fuente
tiposDeDocumentos {
nodes {
name
slug
}
}
categories {
edges {
node {
name
slug
}
}
}
archivos {
nodes {
filePath
}
}
}
}
}
Obtener documentos de un tipo específico:
{
documentosTipo(slug: "articulo", first: 50) {
nodes {
title
descripcion
autores
fecha
}
}
}
4. PERSONAJES (Personajes)
Personas importantes en la historia del internet en Colombia.
Campos disponibles:
title– Nombre del personajeslug– URL amigablecontent– Biografía o descripciónfeaturedImage– Foto del personajeentrevistas– Entrevistas realizadas a este personaje
Consulta para obtener personajes:
{
personajes(first: 50) {
pageInfo {
hasNextPage
endCursor
}
nodes {
title
slug
content
featuredImage {
node {
sourceUrl
altText
}
}
}
}
}
Obtener un personaje específico con sus entrevistas:
{
personajeBy(slug: "nombre-del-personaje") {
title
content
featuredImage {
node {
sourceUrl
}
}
entrevistas {
nodes {
fecha
content
}
}
}
}
5. ENTREVISTAS (Entrevistas)
Entrevistas a personajes clave del proyecto.
Campos disponibles:
title– Título o tema de la entrevistaslug– URL amigablefecha– Fecha de la entrevistacontent– Contenido o preámbulopersonajes– Personas entrevistadastranscripciones– Texto de la entrevistaordenTranscripciones– Orden de las secciones
Consulta para obtener entrevistas:
{
entrevistas(first: 50) {
pageInfo {
hasNextPage
endCursor
}
nodes {
title
slug
fecha
personajes {
nodes {
title
slug
}
}
transcripciones {
nodes {
title
transcripcion
}
}
}
}
}
6. TÉRMINOS (Glosario)
Términos técnicos definidos en el glosario.
Campos disponibles:
title– Términoslug– URL amigablecontent– Definición
Consulta para obtener términos:
{
terminos(first: 100) {
pageInfo {
hasNextPage
endCursor
}
nodes {
title
slug
content
}
}
}
Obtener un término específico:
{
terminoBy(slug: "arpanet") {
title
content
}
}
7. CATEGORÍAS (Categories)
Temas y categorías para clasificar contenido.
Campos disponibles:
name– Nombre de la categoríaslug– URL amigablecount– Cuántos elementos tienen esta categoríadescription– Descripciónchildren– Subcategoríasparent– Categoría padre
Consulta para obtener el árbol de categorías:
{
categories(first: 100) {
pageInfo {
hasNextPage
endCursor
}
nodes {
name
slug
count
description
children {
nodes {
name
slug
count
}
}
parent {
node {
name
slug
}
}
}
}
}
Paginación
Como habrás notado, muchas consultas devuelven pageInfo y usan first. Esto es para paginación: obtener los datos en pequeños lotes en lugar de todo a la vez.
Conceptos clave:
first: N– Obtener los primeros N resultadosafter: "CURSOR– Obtener resultados después del cursorhasNextPage– ¿Hay más resultados?endCursor– Cursor para obtener la siguiente página
Ejemplo de paginación completa:
async function obtenerTodos(tipoContenido) {
const API_URL = 'https://historiasinternetpre.uniandes.edu.co/graphql';
const todos = [];
let tieneMas = true;
let cursor = null;
while (tieneMas) {
const query = `{
${tipoContenido}(first: 100${cursor ? `, after: "${cursor}"` : ''}) {
pageInfo {
hasNextPage
endCursor
}
nodes {
title
slug
fecha
}
}
}`;
const respuesta = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
});
const { data } = await respuesta.json();
const contenido = data[tipoContenido];
todos.push(...contenido.nodes);
tieneMas = contenido.pageInfo.hasNextPage;
cursor = contenido.pageInfo.endCursor;
console.log(`Obtenidos ${todos.length} items...`);
}
return todos;
}
// Usar:
obtenerTodos('eventos').then((eventos) => {
console.log(`Total eventos: ${eventos.length}`);
console.log(eventos);
});
Filtros y búsquedas
Filtrar por estado de publicación:
{
eventos(first: 50, where: { status: PUBLISH }) {
nodes {
title
status
}
}
}
Obtener solo documentos con archivos:
{
documentos(first: 50) {
nodes {
title
archivos {
nodes {
filePath
}
}
}
}
}
Filtrar por categoría:
{
eventos(first: 50, where: { categoryName: "tecnologia" }) {
nodes {
title
categories {
nodes {
name
}
}
}
}
}
Casos de uso prácticos
Caso 1: Crear una línea de tiempo de eventos
const query = `{
eventos(first: 1000) {
nodes {
title
fecha
tipo
content
}
}
}`;
const response = await fetch('https://historiasinternetpre.uniandes.edu.co/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
});
const { data } = await response.json();
// Ordenar por fecha
const eventos = data.eventos.nodes.sort((a, b) => new Date(a.fecha) - new Date(b.fecha));
console.log('Línea de tiempo:');
eventos.forEach((e) => {
console.log(`${e.fecha} - ${e.title}`);
});
Caso 2: Analizar categorías más usadas
const query = `{
categories(first: 100) {
nodes {
name
count
}
}
}`;
const response = await fetch('https://historiasinternetpre.uniandes.edu.co/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
});
const { data } = await response.json();
// Ordenar por cantidad de contenido
const categorias = data.categories.nodes.sort((a, b) => b.count - a.count).slice(0, 10);
console.log('Top 10 categorías:');
categorias.forEach((c) => {
console.log(`${c.name}: ${c.count} items`);
});
Caso 3: Obtener todas las transcripciones de entrevistas
const query = `{
entrevistas(first: 1000) {
nodes {
title
fecha
personajes {
nodes {
title
}
}
transcripciones {
nodes {
title
transcripcion
}
}
}
}
}`;
const response = await fetch('https://historiasinternetpre.uniandes.edu.co/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
});
const { data } = await response.json();
const entrevistas = data.entrevistas.nodes;
// Imprimir como JSON
console.log(JSON.stringify(entrevistas, null, 2));