Learning
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 graphql

Alap 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 graphql

Apollo 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 és useMutation hookok kezelik a betöltési és hibaállapotokat.
  • A mutation után a cache manuális frissítése szükséges lehet.

On this page