Repository navigation
GraphQL Integration Guide
StudentAppBackend provides a typed, schema-driven GraphQL API exposed at POST /graphql, built using Graphiti and the Swift GraphQL reference implementation.
-
Zero Authorization Drift: GraphQL resolvers execute the exact same
AuthorizationServicerules as REST endpoints. No operation in GraphQL bypasses RBAC or authentication barriers. - Type Safety: Swift structs represent input arguments, return objects, and error types without dynamic dictionary parsing.
-
Interactive Developer Playground: An embedded GraphiQL UI is available during development at
GET /graphiql.
The schema defines all types, queries, and mutations using Graphiti's declarative Swift DSL:
final class StudentGraphQLAPI: SchemaBuilder<GraphQLResolver, Request> {
init() throws {
super.init()
// Register Types
try self.register(type: Student.Public.self)
try self.register(type: AuthPayload.self)
// Register Queries
try self.query {
Field("students", at: GraphQLResolver.students)
Field("student", at: GraphQLResolver.student) {
Argument("id", at: \.id)
}
}
// Register Mutations
try self.mutation {
Field("signupStudent", at: GraphQLResolver.signupStudent) {
Argument("input", at: \.input)
}
Field("signup", at: GraphQLResolver.signup) {
Argument("input", at: \.input)
}
Field("login", at: GraphQLResolver.login) {
Argument("input", at: \.input)
}
Field("updateStudent", at: GraphQLResolver.updateStudent) {
Argument("input", at: \.input)
}
}
}
}Retrieves student records scoped by the caller's role.
-
Authentication: Requires
Authorization: Bearer <JWT>header. -
Scoping Behavior:
-
admin/principal/teacher: Returns all student records. -
student: Returns an array containing only their own profile record.
-
query GetAllAccessibleStudents {
students {
id
name
email
role
status
phoneNumber
dob
}
}curl -X POST http://localhost:8080/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_JWT_TOKEN>" \
-d '{
"query": "{ students { id name email role } }"
}'Retrieves a single student profile by ID with strict IDOR prevention.
-
Authentication: Requires
Authorization: Bearer <JWT>header. -
Authorization: Returns
403 Forbiddenif a student attempts to query a foreign ID.
query GetStudentById($id: UUID!) {
student(id: $id) {
id
name
email
role
status
}
}Registers a new student account using the new canonical fields.
- Role is forced to
studentserver-side. - Normalizes country code and contact number.
mutation RegisterStudent($input: StudentGraphQLSignupInput!) {
signupStudent(input: $input) {
id
name
email
role
status
}
}{
"input": {
"firstName": "Jane",
"lastName": "Doe",
"email": "jane.doe@example.com",
"password": "Password123!",
"confirmPassword": "Password123!",
"countryCode": "+1",
"contactNumber": "5559876543"
}
}Authenticates credentials and returns a signed JWT alongside public user details.
mutation AuthenticateUser($input: StudentGraphQLLoginInput!) {
login(input: $input) {
token
user {
id
name
email
role
}
}
}During local development and testing, an embedded GraphiQL interface is served at:
http://localhost:8080/graphiql
In accordance with production hardening standards, GET /graphiql is automatically disabled when app.environment == .production or when ENABLE_GRAPHIQL=false is configured in .env.
