From Zero to GraphQL: Queries, Mutations, Subscriptions, and Access Control in a Real Project
Technology Blogs

From Zero to GraphQL: Queries, Mutations, Subscriptions, and Access Control in a Real Project

Arzoo Jain
Associate Software Engineer

So you’ve heard people say “GraphQL” in standup meetings with the same tone they’d use for “I just got back from a silent meditation retreat.” Calm. Smug. Slightly unbearable.

Here’s the secret nobody tells you: GraphQL is not hard. It’s just REST that learned to say no to your over-fetching habit.

I recently built a full healthcare system POC, patients, doctors, appointments, prescriptions, the works, using Node.js, TypeScript, PostgreSQL, and React. And I learned the four pillars of GraphQL the way you learn anything properly: by breaking them first.

This post is the explainer I wish I had on day one. No jargon you have to Google mid-sentence. By the end, you’ll understand Queries, Mutations, Subscriptions, and Role-Based Access Control (RBAC), and you’ll have a real project to point at, because I’m dropping the repo link at the bottom.

Let’s go.

First, what even is GraphQL?

Imagine you walk into a restaurant and order “food.” The waiter shrugs and brings you everything in the kitchen, three courses, a dessert cart, and somebody else’s birthday cake. That’s REST on a bad day. You ask for a patient’s name and you get their name, blood type, insurance ID, appointment history, and the kitchen sink, whether you wanted it or not.

GraphQL is the waiter who says, “Tell me exactly what you want, and I’ll bring exactly that.” You ask for a name and email. You get a name and email. Nothing more, nothing less. No mystery cake.

It does this through one single endpoint (/graphql) instead of REST’s sprawling cousin reunion of /patients, /patients/:id/appointments, /patients/:id/prescriptions, and so on forever.

Now let’s meet the four characters in this story.

1. Queries, “Just let me read the menu”

A Query is how you ask for data. That’s it. That’s the whole concept. No drama.

query GetPatient {
  getPatient(id: "patient-001") {
    name
    bloodType
    appointments {
      date
      status
    }
  }
}

Look at that shape. You’re not just hitting an endpoint, you’re describing a tree of exactly what you want, including nested relationships, in a single round trip. One request gets you the patient AND their appointments AND the doctor on each appointment, if you ask for it.

Compare that to REST, where you’d be making three separate calls and stitching the results together yourself like some kind of API archaeologist.

The catchy bit to remember: Queries are GraphQL’s “look but don’t touch.” They never change anything in your database. If a Query mutates state, somebody on your team did something deeply wrong and should be gently confronted.

2. Mutations – “Okay, now actually change something”

If Queries are reading the menu, Mutations are placing the order, sending it back because it’s cold, and tipping 20% out of guilt.

A Mutation is how you create, update, or delete data:

mutation BookAppointment {
  bookAppointment(input: {
    patientId: "patient-001"
    doctorId: "doctor-007"
    scheduledAt: "2026-07-01T10:00:00Z"
  }) {
    id
    status
  }
}

Functionally, a Mutation looks almost identical to a Query, same shape, same single endpoint. The only real difference is intent: GraphQL runs Mutations one after another in the order you send them (so two mutations in one request don’t race each other), while Queries can run in parallel because reading data is safe to do all at once.

The phrase to keep: If a Query is a question, a Mutation is a demand with consequences. Treat it accordingly, validate your inputs, because nothing ruins a healthcare POC demo faster than a doctor accidentally prescribing “Yes” as a medication because someone skipped input validation.

Need help structuring queries, mutations, and subscriptions at scale? Talk to our engineers.

3. Subscriptions – “Tell me the moment something happens”

This is where GraphQL stops being polite small talk and starts being genuinely cool.

A Query is “What’s the patient’s appointment status right now?” A Subscription is “Text me the second it changes.” It’s the difference between refreshing your package tracking page every five minutes like a caveman, and getting a push notification the moment your package leaves the depot.

Subscriptions work over WebSocket, not regular HTTP. Your client opens a connection and just… waits. No polling, no setInterval hackery, no shame.

subscription OnAppointmentStatusChanged {
  appointmentStatusChanged(patientId: "patient-001") {
    id
    status
  }
}

In my POC, the moment a doctor updates an appointment from SCHEDULED to IN_PROGRESS, the patient’s dashboard updates live, no refresh button required. The server publishes an event, the subscription catches it, the UI lights up. It genuinely felt like magic the first time I saw it work, right up until it didn’t work, at which point it felt like a personal attack. (Pro tip: check your WebSocket connection before assuming the universe hates you specifically.)

Catchy summary: Queries ask once. Mutations act once. Subscriptions never shut up, in the best possible way.

4. Access Control – “Not everyone gets to see everything”

Here’s the plot twist nobody warns you about: building the API is the easy part. Deciding who’s allowed to do what is where things get spicy.

In a healthcare system, this isn’t optional, it’s the whole point. A patient should not be able to query another patient’s medical records. A nurse shouldn’t be able to delete a doctor’s account. And under no circumstances should anyone except doctors and admins be allowed to look at sensitive fields like a patient’s SSN.

This is Role-Based Access Control, or RBAC if you enjoy acronyms with that slightly bureaucratic flavor.

The idea is simple even if the implementation has layers:

  • Authentication answers “who are you?”, usually a JWT token you get after logging in.
  • Authorization answers “what are you allowed to do, now that I know who you are?”

In practice, this means every single GraphQL operation gets checked against the user’s role before it’s allowed to run:

Role

Can do

PATIENT

See their own appointments and prescriptions only

NURSE

View patients, update appointment status

DOCTOR

All of the above, plus create prescriptions

ADMIN

Everything, including the spicy fields like SSN

The genuinely fun part is field-level access control, not just “can you run this query,” but “can you see this specific field in the response.” A patient querying their own record gets ssn: null even though the field exists in the schema. Same query, different human, different answer. It’s GraphQL quietly redacting a document right in front of you, like a polite government agency.

The line to remember: Authentication is the bouncer checking your ID. Authorization is the bouncer deciding which rooms you’re allowed in once you’re inside. Don’t confuse the two, or you’ll spend three hours debugging a “bug” that’s actually just you skipping a step.

Putting it all together (without losing your mind)

Here’s the mental model that finally made it click for me:

  • Schema = the contract. What data exists, what shapes it comes in.
  • Queries = reading that data.
  • Mutations = changing that data.
  • Subscriptions = getting notified the instant that data changes, live.
  • RBAC = the bouncer making sure everyone only sees and touches what they’re supposed to.

Four concepts. One mental model. No PhD required.

The thing that genuinely surprised me building this out is how composable it all is. Once your schema is solid, Queries and Mutations practically write themselves. Subscriptions are just Mutations with a megaphone. And RBAC is just… rules, applied consistently, everywhere, without exception, the same discipline you’d want from a strict but fair teacher.

Go build the thing

I built a complete working version of everything above, patients, doctors, appointments, prescriptions, real-time subscriptions, full role-based access control, using Node.js, TypeScript, PostgreSQL, and React. No ORM, no shortcuts, raw SQL the whole way through, so you can actually see what’s happening under the hood instead of trusting a magic box.

Repo link: https://github.com/ArzooJain-25/healthcare-graphql-poc

Clone it, run it, break it, fix it. That’s genuinely the fastest way to learn this stuff, not by reading one more blog post (yes, even this one), but by watching a query fail, swearing quietly, and figuring out why.

GraphQL isn’t scary. It’s just REST that finally went to therapy and learned to communicate its needs clearly.

Conclusion

GraphQL feels intimidating until you build something real with it. Once you see Queries fetching exactly the data you asked for, Mutations changing state with intention, Subscriptions pushing live updates, and RBAC keeping every role in its lane, the whole thing starts to feel less like a buzzword and more like a practical way to design cleaner, safer APIs.

That matters even more in healthcare, where the stakes are higher than a slow dashboard or an overstuffed API response. Patients, doctors, nurses, and admins all need different views of the same system, and GraphQL gives you a structured way to serve each of them without duplicating logic everywhere. Start small, break things, fix them, and let the schema become your source of truth. That is when GraphQL stops being “that thing people mention in standups” and starts becoming a tool you actually trust.

Arzoo Jain

Arzoo Jain

Associate Software Engineer

Arzoo is a skilled Associate Software Engineer with strong full-stack development expertise. She’s detail-oriented and genuinely passionate about building smooth, intuitive user experiences, turning ideas into well-crafted, working solutions. Comfortable working across both front-end and back-end systems, Arzoo brings a thoughtful, hands-on approach to her work and is always looking for ways to innovate and improve.

Share This Blog

Read More Similar Blogs

Let’s #Transform Healthcare,# Together.

Partner with us to design, build, and scale digital solutions that drive better outcomes.

BOOK A QUICK CONSULTATION

Have a Healthcare Project in Mind?

Let’s discuss your goals, workflows, and next steps in a focused consultation call.

Calendar icon Schedule a Call

Contact form