Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: migrate to graphql #1

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft

Conversation

roeeyn
Copy link
Contributor

@roeeyn roeeyn commented Sep 14, 2024

Refactor: Migrate to GraphQL

This pull request migrates the existing REST API implementation to use GraphQL, leveraging Apollo Server on the backend and Apollo Client on the frontend. The main objective of this refactor is to address the limitations we encountered with the REST approach and improve the efficiency and flexibility of data fetching in our application.


Summary of Changes

Backend Changes

  • Replaced Express REST API with Apollo Server GraphQL API:

    • Set up Apollo Server using the latest version (@apollo/server), eliminating the need for Express or other frameworks.
    • Defined GraphQL schema using the gql function from graphql-tag.
    • Implemented resolvers for queries and mutations to handle data operations.
  • Data Handling:

    • Maintained the same in-memory data structure (posts and comments) as in the REST API to ensure consistency.
    • Imported data from the existing ./data module.

Frontend Changes

  • Installed and Configured Apollo Client:

    • Installed @apollo/client and graphql packages.
    • Created an Apollo Client instance and wrapped the React application with ApolloProvider.
  • Refactored Components to Use GraphQL:

    • Replaced Axios REST calls with GraphQL queries and mutations using Apollo Client's useQuery and useMutation hooks.
    • Updated the following components:
      • PostList: Fetches and displays the list of posts.
      • PostDetail: Fetches and displays a single post with its comments, and handles adding and deleting comments.
      • CreatePost: Provides a form to create new posts.
  • Organized GraphQL Queries and Mutations:

    • Created src/graphql/queries.ts and src/graphql/mutations.ts to define and export GraphQL operations.

Why We Migrated to GraphQL

Limitations of the REST Approach

  • Multiple Requests for Related Data:

    • In the REST implementation, fetching a post and its comments required multiple API calls (e.g., /posts/:id and /posts/:id/comments).
    • This led to increased network overhead and more complex client-side logic to manage asynchronous requests.
  • Inefficient Data Refetching:

    • After mutations like deleting a post or comment, the client had to refetch the entire list of posts or comments to stay updated.
    • This approach was inefficient and could result in redundant data fetching and potential stale data issues.

Benefits of GraphQL

  • Fetch Multiple Resources in a Single Request:

    • GraphQL allows us to fetch nested and related data in one request.
    • Example: Fetching a post along with its comments using a single query.
  • Efficient Data Fetching:

    • Clients can request exactly the data they need, reducing over-fetching or under-fetching.
    • Simplifies client-side data management and state handling.
  • Improved Performance:

    • Reduces the number of network requests.
    • Minimizes the amount of data transferred over the network.
  • Simplified Client Logic:

    • Eliminates the need for chaining multiple REST calls.
    • Apollo Client provides caching and other features that enhance the developer experience.

Detailed Implementation

Backend

  • Server Setup:

    • Used startStandaloneServer from @apollo/server/standalone to create a standalone GraphQL server without additional frameworks.
    • Enabled the built-in GraphQL Playground for testing and exploration.
  • Schema Definition:

    • Defined types for Post, Comment, Query, and Mutation using GraphQL SDL (Schema Definition Language).
    • Used the gql function to parse the schema.
  • Resolvers:

    • Implemented resolver functions for queries and mutations to handle data fetching and manipulation.
    • Included field resolvers for nested data (e.g., Post.comments).

Frontend

  • Apollo Client Configuration:

    • Created an Apollo Client instance pointing to the GraphQL server endpoint.
    • Used InMemoryCache for caching query results.
  • Component Refactoring:

    • PostList Component:

      • Replaced Axios calls with the useQuery hook to fetch posts.
      • Used the useMutation hook for deleting posts, with refetchQueries to update the list after deletion.
    • PostDetail Component:

      • Used useQuery to fetch a post and its comments.
      • Implemented useMutation for creating and deleting comments, with refetchQueries to refresh the data.
    • CreatePost Component:

      • Replaced Axios post request with the useMutation hook to create new posts.
      • After creation, redirected the user to the home page and refetched the posts list.
  • GraphQL Operations Organization:

    • Organized GraphQL queries and mutations in separate files for better maintainability.

How This Improves the Application

  • Simplifies Data Fetching:

    • Fetching posts and comments now requires a single query, simplifying the data flow.
  • Reduces Network Overhead:

    • Fewer requests are made to the server, and only necessary data is transferred.
  • Enhances Developer Experience:

    • Apollo Client's hooks (useQuery, useMutation) provide a declarative approach to data fetching and state management.
    • Built-in caching reduces the need for manual state updates.
  • Improves Performance:

    • Efficient data fetching and caching lead to faster load times and a more responsive UI.

How to Test the Changes

  1. Start the GraphQL Server:

    cd server
    npx ts-node src/index.ts
  2. Start the React Application:

    cd client
    npm start
  3. Verify Functionality:

    • Home Page: Should display the list of posts fetched via GraphQL.
    • Post Detail Page: Should display post details and comments, allowing adding and deleting comments.
    • Create Post Page: Should allow creating a new post and reflect the changes on the home page.

Future Improvements

  • Type Generation:

    • Use tools like graphql-code-generator to generate TypeScript types from GraphQL schema for better type safety.
  • Optimistic UI Updates:

    • Implement optimistic responses in mutations to provide immediate UI feedback.
  • Subscriptions:

    • Introduce GraphQL subscriptions for real-time updates (e.g., new comments appearing without page refresh).
  • Data Persistence:

    • Replace in-memory data with a persistent database to retain data between server restarts.

Conclusion

This refactor demonstrates the advantages of using GraphQL over REST in scenarios where efficient data fetching and flexibility are important. By migrating to GraphQL, we've simplified the data flow, reduced network overhead, and improved the overall developer and user experience.


Thank you for reviewing this pull request. Please let me know if you have any questions or suggestions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant