GraphQL
Gyakorlati példák
Backend (Apollo Server) és frontend (Apollo Client) alap beállítások, query és mutation példákkal.
Gyakorlati példák frontend és backend oldalon
Backend: Apollo Server + Node.js
Telepítés:
npm install @apollo/server graphqlAlap szerver felállítása:
const { ApolloServer } = require('@apollo/server');
const { startStandaloneServer } = require('@apollo/server/standalone');
const typeDefs = `#graphql
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
type Query {
users: [User!]!
user(id: ID!): User
posts: [Post!]!
post(id: ID!): Post
}
type Mutation {
createPost(title: String!, content: String!, authorId: ID!): Post!
}
`;
const resolvers = {
Query: {
users: () => db.users.findAll(),
user: (_, { id }) => db.users.findById(id),
posts: () => db.posts.findAll(),
post: (_, { id }) => db.posts.findById(id),
},
User: {
posts: (parent) => db.posts.findByAuthorId(parent.id),
},
Post: {
author: (parent) => db.users.findById(parent.authorId),
},
Mutation: {
createPost: (_, args) => db.posts.create(args),
},
};
const server = new ApolloServer({ typeDefs, resolvers });
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
context: async ({ req }) => ({
// Auth token feldolgozása
currentUser: await getUserFromToken(req.headers.authorization),
}),
});
console.log(`🚀 Szerver fut: ${url}`);Frontend: Apollo Client + React / Next.js
Telepítés:
npm install @apollo/client graphqlApollo Provider beállítása:
// lib/apolloClient.js
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client';
export const client = new ApolloClient({
link: new HttpLink({
uri: process.env.NEXT_PUBLIC_GRAPHQL_URL,
}),
cache: new InMemoryCache(),
});// app/layout.jsx (Next.js App Router)
'use client';
import { ApolloProvider } from '@apollo/client';
import { client } from '@/lib/apolloClient';
export default function RootLayout({ children }) {
return (
<html>
<body>
<ApolloProvider client={client}>
{children}
</ApolloProvider>
</body>
</html>
);
}Query hook egy komponensben:
// components/UserProfile.jsx
import { useQuery, gql } from '@apollo/client';
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts {
id
title
publishedAt
}
}
}
`;
export function UserProfile({ userId }) {
const { data, loading, error } = useQuery(GET_USER, {
variables: { id: userId },
});
if (loading) return <div>Betöltés...</div>;
if (error) return <div>Hiba: {error.message}</div>;
const { user } = data;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
<h2>Bejegyzések</h2>
<ul>
{user.posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}Mutation hook:
// components/CreatePost.jsx
import { useMutation, gql } from '@apollo/client';
const CREATE_POST = gql`
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
content
}
}
`;
export function CreatePost() {
const [createPost, { loading, error }] = useMutation(CREATE_POST, {
// Cache frissítése a mutation után
update(cache, { data: { createPost } }) {
cache.modify({
fields: {
posts(existingPosts = []) {
const newPostRef = cache.writeFragment({
data: createPost,
fragment: gql`
fragment NewPost on Post {
id
title
}
`,
});
return [newPostRef, ...existingPosts];
},
},
});
},
});
const handleSubmit = async (formData) => {
try {
await createPost({
variables: {
input: {
title: formData.title,
content: formData.content,
},
},
});
} catch (err) {
console.error('Hiba a bejegyzés létrehozásakor:', err);
}
};
return (
<form onSubmit={handleSubmit}>
{/* form mezők */}
<button type="submit" disabled={loading}>
{loading ? 'Létrehozás...' : 'Bejegyzés létrehozása'}
</button>
{error && <p>Hiba: {error.message}</p>}
</form>
);
}Rövid összefoglaló
- Az Apollo Server a legnépszerűbb Node.js GraphQL szerver.
- A resolver context-ben adjuk át az adatbázis-kapcsolatot és az autentikált felhasználót.
- Az Apollo Client a legelterjedtebb React/Next.js GraphQL kliens.
- A
useQueryésuseMutationhookok kezelik a betöltési és hibaállapotokat. - A mutation után a cache manuális frissítése szükséges lehet.