This document provides comprehensive documentation for the Todo GraphQL API endpoints.
📖 Back to Main README - Project setup and technical details
All protected operations require a Bearer token in the Authorization header:
Authorization: Bearer your_sanctum_token_here
- Register a new user via
registermutation - Login existing user via
loginmutation - Use the returned token for subsequent requests
- URL:
POST /graphql - Content-Type:
application/json - Playground:
GET /graphiql(development only)
type User {
id: ID!
name: String!
email: String!
email_verified_at: DateTime
created_at: DateTime!
updated_at: DateTime!
todos: [Todo!]!
}type Todo {
id: ID!
user: User!
title: String!
description: String
completed: Boolean!
created_at: DateTime!
updated_at: DateTime!
}type AuthPayload {
user: User!
token: String!
}type Message {
message: String!
}Get the currently authenticated user.
Authentication: Required
query {
me {
id
name
email
todos {
id
title
completed
}
}
}Response:
{
"data": {
"me": {
"id": "1",
"name": "John Doe",
"email": "john@example.com",
"todos": [...]
}
}
}Get paginated list of todos for the authenticated user.
Authentication: Required
query {
todos(first: 10, page: 1) {
data {
id
title
description
completed
created_at
}
paginatorInfo {
currentPage
lastPage
perPage
total
}
}
}Arguments:
first(Int): Number of items per pagepage(Int): Page number
Response:
{
"data": {
"todos": {
"data": [
{
"id": "1",
"title": "Learn GraphQL",
"description": "Study GraphQL basics",
"completed": false,
"created_at": "2026-03-16 10:00:00"
}
],
"paginatorInfo": {
"currentPage": 1,
"lastPage": 1,
"perPage": 10,
"total": 1
}
}
}
}Get a single todo by ID.
Authentication: Not required (public query)
query {
todo(id: "1") {
id
title
description
completed
user {
name
email
}
}
}Arguments:
id(ID!): Todo ID
Response:
{
"data": {
"todo": {
"id": "1",
"title": "Learn GraphQL",
"description": "Study GraphQL basics",
"completed": false,
"user": {
"name": "John Doe",
"email": "john@example.com"
}
}
}
}Returns null if todo not found.
Find a user by ID or email.
Authentication: Not required
query {
user(id: "1") {
id
name
email
}
}OR
query {
user(email: "john@example.com") {
id
name
email
}
}Arguments:
id(ID): User ID (mutually exclusive with email)email(String): User email (mutually exclusive with id)
Response:
{
"data": {
"user": {
"id": "1",
"name": "John Doe",
"email": "john@example.com"
}
}
}Returns null if user not found.
Get paginated list of all users.
Authentication: Not required
query {
users(first: 10, name: "John") {
data {
id
name
email
}
paginatorInfo {
currentPage
lastPage
perPage
total
}
}
}Arguments:
first(Int): Number of items per page (default: 10)name(String): Filter by name (LIKE search)
Register a new user account.
Authentication: Not required
mutation {
register(
name: "John Doe"
email: "john@example.com"
password: "securepassword123"
) {
user {
id
name
email
}
token
}
}Arguments:
name(String!): User's full nameemail(String!): Unique email addresspassword(String!): Password (min 8 characters)
Response:
{
"data": {
"register": {
"user": {
"id": "1",
"name": "John Doe",
"email": "john@example.com"
},
"token": "1|abc123def456..."
}
}
}Authenticate an existing user.
Authentication: Not required
mutation {
login(
email: "john@example.com"
password: "securepassword123"
) {
user {
id
name
email
}
token
}
}Arguments:
email(String!): User emailpassword(String!): User password
Response:
{
"data": {
"login": {
"user": {
"id": "1",
"name": "John Doe",
"email": "john@example.com"
},
"token": "1|abc123def456..."
}
}
}Error Response (invalid credentials):
{
"errors": [
{
"message": "Internal server error",
"extensions": {
"debugMessage": "Invalid credentials"
}
}
]
}Logout the current user (revoke token).
Authentication: Required
mutation {
logout {
message
}
}Response:
{
"data": {
"logout": {
"message": "Successfully logged out"
}
}
}Create a new todo for the authenticated user.
Authentication: Required
mutation {
createTodo(
title: "Learn GraphQL"
description: "Study GraphQL basics"
completed: false
) {
id
title
description
completed
created_at
}
}Arguments:
title(String!): Todo title (max 255 chars)description(String): Todo description (optional)completed(Boolean): Completion status (default: false)
Response:
{
"data": {
"createTodo": {
"id": "1",
"title": "Learn GraphQL",
"description": "Study GraphQL basics",
"completed": false,
"created_at": "2026-03-16 10:00:00"
}
}
}Update an existing todo.
Authentication: Required (user must own the todo)
mutation {
updateTodo(
id: "1"
title: "Learn Advanced GraphQL"
completed: true
) {
id
title
completed
updated_at
}
}Arguments:
id(ID!): Todo IDtitle(String): New title (optional)description(String): New description (optional)completed(Boolean): New completion status (optional)
Response:
{
"data": {
"updateTodo": {
"id": "1",
"title": "Learn Advanced GraphQL",
"completed": true,
"updated_at": "2026-03-16 10:30:00"
}
}
}Returns null if todo not found or user doesn't own it.
Delete a todo.
Authentication: Required (user must own the todo)
mutation {
deleteTodo(id: "1") {
id
title
}
}Arguments:
id(ID!): Todo ID
Response:
{
"data": {
"deleteTodo": {
"id": "1",
"title": "Learn Advanced GraphQL"
}
}
}Returns null if todo not found or user doesn't own it.
The API handles errors gracefully:
- Authentication errors: Return "Unauthorized" message
- Not found objects: Return
nullinstead of throwing errors - Validation errors: Return detailed validation messages
- Invalid credentials: Return "Invalid credentials" message
Currently no rate limiting is implemented. Consider adding middleware for production use.
The API uses cursor-based pagination compatible with Lighthouse's @paginate directive.
first: Number of items to fetchpage: Page number (for simple pagination)- Response includes
paginatorInfowith metadata
Use the GraphiQL playground at /graphiql for testing all operations.
Example test flow:
- Register a new user
- Use the returned token for authenticated requests
- Create, update, and delete todos
- Logout to revoke the token