5.9 KiB
5.9 KiB
DI-004: Esquema GraphQL
Proyecto: Sistema de Registro de Estudiantes Fecha: 2026-01-07
1. Schema Completo
# ═══════════════════════════════════════════════════════════════
# TYPES
# ═══════════════════════════════════════════════════════════════
type Student {
id: Int!
name: String!
email: String!
totalCredits: Int!
enrollments: [Enrollment!]!
}
type Subject {
id: Int!
name: String!
credits: Int!
professor: Professor!
enrolledStudents: [Student!]!
}
type Professor {
id: Int!
name: String!
subjects: [Subject!]!
}
type Enrollment {
id: Int!
student: Student!
subject: Subject!
enrolledAt: DateTime!
}
type AvailableSubject {
subject: Subject!
isAvailable: Boolean!
unavailableReason: String
}
type Classmate {
subjectName: String!
students: [String!]!
}
# ═══════════════════════════════════════════════════════════════
# QUERIES
# ═══════════════════════════════════════════════════════════════
type Query {
# Estudiantes
students: [Student!]!
student(id: Int!): Student
# Materias
subjects: [Subject!]!
subject(id: Int!): Subject
availableSubjects(studentId: Int!): [AvailableSubject!]!
# Profesores
professors: [Professor!]!
professor(id: Int!): Professor
# Compañeros de clase
classmates(studentId: Int!): [Classmate!]!
}
# ═══════════════════════════════════════════════════════════════
# MUTATIONS
# ═══════════════════════════════════════════════════════════════
type Mutation {
# Estudiantes
createStudent(input: CreateStudentInput!): StudentPayload!
updateStudent(id: Int!, input: UpdateStudentInput!): StudentPayload!
deleteStudent(id: Int!): DeletePayload!
# Inscripciones
enrollStudent(input: EnrollInput!): EnrollmentPayload!
unenrollStudent(enrollmentId: Int!): DeletePayload!
}
# ═══════════════════════════════════════════════════════════════
# INPUTS
# ═══════════════════════════════════════════════════════════════
input CreateStudentInput {
name: String!
email: String!
}
input UpdateStudentInput {
name: String
email: String
}
input EnrollInput {
studentId: Int!
subjectId: Int!
}
# ═══════════════════════════════════════════════════════════════
# PAYLOADS (Union para errores)
# ═══════════════════════════════════════════════════════════════
type StudentPayload {
student: Student
errors: [String!]
}
type EnrollmentPayload {
enrollment: Enrollment
errors: [String!]
}
type DeletePayload {
success: Boolean!
errors: [String!]
}
# ═══════════════════════════════════════════════════════════════
# SCALARS
# ═══════════════════════════════════════════════════════════════
scalar DateTime
2. Ejemplos de Queries
Listar estudiantes con inscripciones
query GetStudents {
students {
id
name
email
totalCredits
enrollments {
subject { name professor { name } }
}
}
}
Materias disponibles para inscripción
query GetAvailableSubjects($studentId: Int!) {
availableSubjects(studentId: $studentId) {
subject { id name credits professor { name } }
isAvailable
unavailableReason
}
}
Compañeros de clase
query GetClassmates($studentId: Int!) {
classmates(studentId: $studentId) {
subjectName
students
}
}
3. Ejemplos de Mutations
Crear estudiante
mutation CreateStudent {
createStudent(input: { name: "Juan Pérez", email: "juan@email.com" }) {
student { id name email }
errors
}
}
Inscribir en materia
mutation Enroll {
enrollStudent(input: { studentId: 1, subjectId: 3 }) {
enrollment {
id
subject { name }
enrolledAt
}
errors
}
}
4. DataLoaders (Evitar N+1)
| DataLoader | Carga Batch |
|---|---|
StudentByIdDataLoader |
Estudiantes por IDs |
SubjectByIdDataLoader |
Materias por IDs |
ProfessorByIdDataLoader |
Profesores por IDs |
EnrollmentsByStudentDataLoader |
Inscripciones por estudiante |
SubjectsByProfessorDataLoader |
Materias por profesor |
5. Errores de Negocio
| Código | Mensaje | Contexto |
|---|---|---|
MAX_ENROLLMENTS |
"Máximo 3 materias permitidas" | enrollStudent |
SAME_PROFESSOR |
"Ya tienes materia con este profesor" | enrollStudent |
DUPLICATE_EMAIL |
"Email ya registrado" | createStudent |
NOT_FOUND |
"Estudiante no encontrado" | updateStudent |