-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphql-masterclass-tutorial.html
More file actions
149 lines (135 loc) · 8.25 KB
/
Copy pathgraphql-masterclass-tutorial.html
File metadata and controls
149 lines (135 loc) · 8.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GraphQL APIs Masterclass 🔗</title>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<!-- Highlight.js for Code Formatting -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
<style>
:root {
--bg-color: #1e111a; /* Dark Fuchsia base */
--primary-color: #e879f9; /* Pink/Fuchsia */
--primary-glow: rgba(232, 121, 249, 0.4);
--text-main: #f8fafc; --text-muted: #94a3b8;
--border-color: rgba(255, 255, 255, 0.08);
--card-border: rgba(255, 255, 255, 0.1);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Plus Jakarta Sans', sans-serif; background-color: var(--bg-color); color: var(--text-main); line-height: 1.6; background-image: radial-gradient(at 0% 0%, rgba(232, 121, 249, 0.15) 0px, transparent 50%); background-attachment: fixed; min-height: 100vh; }
.layout { display: flex; gap: 2.5rem; max-width: 1400px; margin: 0 auto; padding: 3rem 2rem; }
.sidebar { width: 280px; flex-shrink: 0; position: sticky; top: 3rem; max-height: calc(100vh - 6rem); overflow-y: auto; background: rgba(30, 17, 26, 0.8); border: 1px solid var(--card-border); border-radius: 16px; padding: 1.5rem; backdrop-filter: blur(12px); }
.sidebar h3 { margin-bottom: 1rem; font-size: 1.1rem; text-transform: uppercase; letter-spacing: 1.5px; color: var(--primary-color); border-bottom: 1px solid var(--card-border); padding-bottom: 1rem; }
.sidebar ul { list-style: none; }
.sidebar li { margin-bottom: 0.3rem; }
.nav-section { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 1px; color: var(--text-muted); margin: 1.5rem 0 0.5rem 0; padding-left: 0.5rem; font-weight: 700; }
.sidebar a { text-decoration: none; color: var(--text-muted); display: block; padding: 0.5rem 1rem; border-radius: 8px; transition: all 0.3s ease; font-size: 0.95rem; font-weight: 500; }
.sidebar a.active { background: rgba(232, 121, 249, 0.2); color: #fff; border-left: 3px solid var(--primary-color); }
.sidebar a:hover:not(.active) { background: rgba(232, 121, 249, 0.15); color: var(--primary-color); transform: translateX(5px); }
.main-content { flex: 1; min-width: 0; }
header { text-align: center; margin-bottom: 3rem; }
h1 { font-size: 3rem; font-weight: 800; margin-bottom: 1rem; background: linear-gradient(135deg, var(--primary-color) 0%, #fbcfe8 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.content-card { background: rgba(30, 17, 26, 0.6); border: 1px solid var(--card-border); border-radius: 16px; padding: 2.5rem; margin-bottom: 2rem; }
h2 { font-size: 1.8rem; margin-bottom: 1.5rem; color: #fff; border-bottom: 1px solid var(--border-color); padding-bottom: 1rem; }
p { margin-bottom: 1rem; font-size: 1.1rem; color: #cbd5e1; }
ul { margin-left: 1.5rem; margin-bottom: 1rem; color: #cbd5e1; }
pre { background: #010409 !important; border: 1px solid var(--border-color); border-radius: 12px; padding: 1.5rem !important; margin: 1.5rem 0; overflow-x: auto; }
code { font-family: 'JetBrains Mono', monospace !important; font-size: 0.95rem; }
.explanation { background: rgba(232, 121, 249, 0.1); border-left: 4px solid var(--primary-color); padding: 1rem 1.5rem; border-radius: 0 8px 8px 0; margin: 1.5rem 0; }
.query-box { background: #18181b; padding: 1rem; border-radius: 8px; border: 1px dashed var(--primary-color); color: #f472b6; font-family: monospace; display: flex; justify-content: space-between; margin-bottom: 1rem; }
</style>
</head>
<body>
<div class="layout">
<!-- Sidebar Navigation -->
<aside class="sidebar">
<h3>🗂️ Tutorials Link</h3>
<nav id="dynamic-sidebar">
<ul>
<li><a href="index.html">🏠 Home Hub</a></li>
<li class="nav-section">Databases / Lang</li>
<li><a href="graphql-masterclass-tutorial.html" class="active">🔗 GraphQL APIs</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="main-content">
<header>
<h1>GraphQL APIs Masterclass 🔗</h1>
<p class="subtitle">Ask exactly for what you need. No more under-fetching or over-fetching!</p>
</header>
<div class="content-card">
<h2>1. GraphQL VS REST APIs</h2>
<p>Standard REST APIs (Express) me hum <code>GET /api/users/1</code> call karty hn aur wo humein User ki poori kundali (name, email, age, dob, address, orders) la k daita hai. Lkn frontend par ho sakta ha humein sirf "name" aur "email" chahiye ho Profile picture k neechy dikhanay k liye. Isy <strong>Over-fetching</strong> kehtay hain.</p>
<div class="explanation">
<p>👉 <strong>GraphQL</strong> ek Query language ha. Is me Frontend batata hai k "Mujhy User chahiye jiski ID 1 ho, aur uska sirf name aor uske orders ka total price le kar aao". Backend sirf utna hi bhejy ga! Ek single endpoint <code>/graphql</code> hota ha.</p>
</div>
</div>
<div class="content-card">
<h2>2. Typed Schema (`typeDefs`)</h2>
<p>GraphQL strongly typed hai. Aap ko backend pe har Model ka structure define krna parta ha.</p>
<pre><code class="language-graphql">type User {
id: ID!
name: String!
email: String!
orders: [Order]!
}
type Order {
id: ID!
totalPrice: Float!
itemCount: Int
}
# Queries are like GET requests
type Query {
getUser(id: ID!): User
getAllUsers: [User]
}
# Mutations are like POST/PUT/DELETE requests
type Mutation {
createUser(name: String!, email: String!): User
}
</code></pre>
</div>
<div class="content-card">
<h2>3. Resolvers (The Logic)</h2>
<p>GraphQL ko schema to mil gaya, lkn usko data kahan sy uthana hai? Wo <strong>Resolvers</strong> btaty hain. Yeh exactly controllers ki tarah hote hain.</p>
<pre><code class="language-javascript">const resolvers = {
Query: {
getUser: async (_, { id }) => {
return await UserModel.findById(id);
},
getAllUsers: async () => {
return await UserModel.find({});
}
},
Mutation: {
createUser: async (_, { name, email }) => {
const newUser = new UserModel({ name, email });
return await newUser.save();
}
},
// Yeh GraphQL ka magic hai! User query hotay wkt, us k 'orders' array ko resolve karega idhar sy.
User: {
orders: async (parent_user) => {
// "parent_user" wo user ha jis par query chal rai hai
return await OrderModel.find({ userId: parent_user.id });
}
}
};
</code></pre>
</div>
<div class="content-card">
<h2>4. The Danger: N+1 Query Problem ⚠️</h2>
<div class="explanation" style="border-left-color: #ef4444; background: rgba(239,68,68,0.1);">
<p>🚨 GraphQL me ek bara masla "N+1 Problem" ha. Farx kro aap ne 100 Users fetch kye, aor sath hi <code>orders</code> query kye. GraphQL pehlay 1 DB query chalaye ga users lane k loye (1). Phir har akelly user k orders lny k liye wo <code>User.orders</code> resolver 100 dafa run kary ga (N). Total DB hits = 101!</p>
<p><strong>Solution: <code>DataLoader</code> (Facebook batching logic):</strong> Jo un 100 users ki ID ko ek array <code>[1,2...100]</code> mein gucha bana kar DB me single <code>$in</code> query marta hai. Boom! 101 queries redced to 2 queries!</p>
</div>
</div>
</main>
</div>
</body>
</html>