logoGERASOFT
Blog

From Idea to App - GraphQL API for Task Management

Reading time: 4-12 minsTechnicality: 5/5Last updated: Feb 24, 2025
From Idea to App - GraphQL API for Task Management

Now that our backend supports user authentication, we can extend it to handle task management, enabling us to replace the mock API on the frontend with the real one.

Upcoming

We are going to split the work into layers:

Our goal is to let users manage tasks. Both users and tasks belong to an organisation, and users within an organisation can access the tasks of the organisation. Task management operations are:

  • getTasks(filters?, sortBy?, limit?, offset?) – Retrieves tasks within the organisation, with optional filtering and sorting.
  • getTaskById(_id) – Fetches a specific task.
  • createTask(taskProps) – Creates a new task within the organisation.
  • updateTask(_id, updatedFields) – Updates a specified task with new data.
  • deleteTask(_id) – Deletes a task.

Create Task mongoose schema

ClickUp ticket

To enable task management, we first need a database schema that defines tasks and their attributes.

We reused the existing Task schema in @repo/validation-schema, and extended it with some fields:

  • _id: String – the ID of the task
  • orgId: String – ID of the organisation the task belongs to
  • name: String – name of the task
  • isCompleted: Boolean – completion indicator
  • completedAt: Number? – when the task was marked completed
  • updatedAt: Number – when the task was last updated
  • createdAt: Number – when the task was created

We then created a new Mongoose schema in @repo/mongodb-helpers based on these types.

Since the Task type is inferred from the updated task schema, new fields (such as orgId) were introduced, which are currently unknown to the frontend. This caused a temporary mismatch between the API and frontend types. To address this, we introduced a transitional type, MockTaskType, to maintain compatibility until the frontend is updated.

GitHub changes

Create task service

ClickUp ticket

The task service is responsible for handling task management – creating, reading, updating, and deleting tasks (CRUD operations).

Service factory

For the context to pass down to the handlers we will initialise resources:

  • Database connection with the connection string (DB_CONNECTION_STRING) coming from the config.
  • TaskModel to perform database operations on the tasks collection.

Handlers

  • getTaskById – Finds and returns the task that matches the _id and orgId supplied.
  • getTasks – Retrieves a list of tasks based on filters, with sorting (sortBy), pagination (limit, offset), and formatted filters.
  • createTask – Creates a new task using the provided arguments and returns the created task as an object.
  • updateTask – Updates an existing task by _id and orgId, applies the provided update fields, and returns the updated task.
  • deleteTask – Deletes the task that matches the _id and orgId, then returns true upon success.

Utility functions

  • formatFilters – formats object based filters into mongoose syntax filters

GitHub changes

Create GraphQL schema

ClickUp ticket

We defined the queries, mutations, inputs, and output types in the GraphQL schema:

  1. Task Type Definition:
    • Fields: _id, orgId, name, isCompleted, completedAt, updatedAt, createdAt.
  2. Task Filtering:
    • TaskFilters allows filtering by _id and name using StringFilters.
  3. Sorting Mechanism:
    • TaskSortField enum: Supports sorting by name, createdAt, updatedAt.
    • TaskSortBy input: Specifies sorting field and method (SortMethodasc/desc).
  4. Query Operations:
    • getTasks: Retrieves a paginated list of tasks with filtering, sorting, and limits.
    • getTaskById: Fetches a single task by its _id.
  5. Mutation Operations:
    • createTask: Creates a new task with required name.
    • updateTask: Updates a task’s name or isCompleted status.
    • deleteTask: Deletes a task by _id, returning a boolean status.

This schema enables task management with querying, filtering, sorting, and CRUD operations via GraphQL.

You may have noticed that we don’t filter by orgId. This is because we will automatically extract it from the authorisation tokens. You can see how in the ntext section.

GitHub changes

API integration

ClickUp ticket

Now that we have a task service and a GraphQL schema, we need to connect them via resolvers.

Integrating task-service

  • Initialised taskService as a plugin, extending the fastify instance with it.
  • Extended the GraphQL contextFunction with fastify.taskService, so they are available in the resolvers.

Resolvers

Query

  • getTasks – Fetches the tasks using taskService.getTasks, supporting filtering, sorting, and pagination. Requires authentication and extracts orgId from the token to filter by.
  • getTaskById – Retrieves a single task using taskService.getTaskById. Requires authentication.

Mutation

  • createTask – Creates a new task using taskService.createTask, associating it with the authenticated user’s orgId. Requires authentication and extracts orgId from the token.
  • updateTask – Updates an existing task using taskService.updateTask, allowing changes to name and isCompleted. Requires authentication and extracts orgId from the token to ensure the task belongs to the user’s organisation.
  • deleteTask – Deletes a task using taskService.deleteTask. Requires authentication and extracts orgId from the token to ensure only tasks within the user’s organisation can be deleted.

Putting it all together

With the resolvers ready, we will extend the executableSchema, merging the taskTypeDefs together with their corresponding taskResolvers.

GitHub changes

GitHub links

Next steps

Now that our API supports user and task management, the next step is to integrate it with our frontend app:

  1. Implement Authentication UI – Develop authentication screens and logic.
  2. Replace Mock API – Connect the frontend to the new task API, ensuring proper state management.

Here's how our timeline look like now:

12345
Implement authentication frontend
5 d