GraphQL vs REST – nowy sposób na API

TL;DR: GraphQL to query language dla API stworzone przez Facebook które pozwala klientom request dokładnie tych danych których potrzebują. W przeciwieństwie do REST (multiple endpoints), GraphQL ma jeden endpoint z flexible queries. Główne zalety: no over-fetching, strong typing, real-time subscriptions.

Dlaczego GraphQL może zastąpić REST API?

REST API to jak zamówienie menu w restauracji – dostajesz pre-defined set dishes. GraphQL to jak składanie zamówienia à la carte – wybierasz dokładnie co chcesz. Facebook stworzył GraphQL w 2012 aby rozwiązać problemy mobile apps: over-fetching data, multiple round trips i versioning hell. Open source release w 2015 sparked revolution w API design.

GraphQL został open-sourced przez Facebook w 2015. Github GraphQL API (v4) launched w early 2016 jako pierwszy major adoption. W 2017 GraphQL gaining significant traction w enterprise applications.

Co się nauczysz:

  • Różnice między GraphQL a REST architecture
  • GraphQL schema, queries, mutations i subscriptions
  • Zalety: single endpoint, precise data fetching, strong typing
  • Wady: complexity, caching challenges, learning curve
  • Kiedy wybierać GraphQL vs REST dla projektów
Wymagania wstępne: Znajomość REST API, podstawy HTTP, doświadczenie z JSON, basic understanding frontend-backend communication.

REST API – current standard

Jak działa REST

REST (Representational State Transfer) organizuje API wokół resources dostępnych przez URLs z HTTP methods:

// REST API endpoints
GET    /api/users/123           // Get user
POST   /api/users               // Create user  
PUT    /api/users/123           // Update user
DELETE /api/users/123           // Delete user

GET    /api/users/123/posts     // Get user's posts
GET    /api/posts/456/comments  // Get post's comments
GET    /api/users/123/profile   // Get user's profile

REST problems w praktyce

// Problem 1: Over-fetching - dostajesz więcej niż potrzebujesz
// GET /api/users/123 returns:
{
  "id": 123,
  "name": "John Doe",
  "email": "john@example.com",
  "bio": "Long biography text...",
  "profilePicture": "base64-encoded-image-data",
  "preferences": { /* large object */ },
  "statistics": { /* complex stats */ }
}
// Ale ty potrzebujesz tylko name i email!

// Problem 2: Under-fetching - multiple round trips
async function loadUserDashboard(userId) {
  const user = await fetch(`/api/users/${userId}`);           // Request 1
  const posts = await fetch(`/api/users/${userId}/posts`);   // Request 2  
  const comments = await fetch(`/api/users/${userId}/comments`); // Request 3
  
  // 3 network requests dla jednej screen!
}

// Problem 3: Versioning nightmare
// /api/v1/users vs /api/v2/users
// Multiple API versions w maintenance
Pułapka: REST often leads do N+1 problem – jeśli potrzebujesz list of items plus details dla każdego item, robisz 1 + N network requests.

GraphQL – query language for APIs

GraphQL fundamentals

GraphQL ma trzy główne operations:

OperationPurposeREST Equivalent
QueryRead dataGET requests
MutationModify dataPOST/PUT/DELETE
SubscriptionReal-time updatesWebSockets/SSE

GraphQL query example

# Single GraphQL query replaces multiple REST calls
query UserDashboard($userId: ID!) {
  user(id: $userId) {
    name
    email
    posts(limit: 5) {
      title
      publishedAt
      comments(limit: 3) {
        content
        author {
          name
        }
      }
    }
    profile {
      bio
      location
    }
  }
}

# Response - exactly what you requested
{
  "data": {
    "user": {
      "name": "John Doe",
      "email": "john@example.com",
      "posts": [
        {
          "title": "My First Post",
          "publishedAt": "2017-06-15",
          "comments": [
            {
              "content": "Great post!",
              "author": { "name": "Alice" }
            }
          ]
        }
      ],
      "profile": {
        "bio": "Software developer",
        "location": "San Francisco"
      }
    }
  }
}
Pro tip: GraphQL queries są self-documenting. Query structure shows exactly jakie data będzie returned, making frontend-backend communication crystal clear.

GraphQL Schema – contract between client i server

Defining schema

# schema.graphql - Type definitions
type User {
  id: ID!                    # ! means required field
  name: String!
  email: String!
  bio: String
  posts: [Post!]!           # Array of Posts
  profile: Profile
}

type Post {
  id: ID!
  title: String!
  content: String!
  publishedAt: String!
  author: User!
  comments: [Comment!]!
}

type Comment {
  id: ID!
  content: String!
  author: User!
  post: Post!
}

type Profile {
  bio: String
  location: String
  website: String
}

# Root types - entry points do API
type Query {
  user(id: ID!): User
  users(limit: Int, offset: Int): [User!]!
  post(id: ID!): Post
  posts(authorId: ID): [Post!]!
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): Boolean!
  
  createPost(input: CreatePostInput!): Post!
  addComment(postId: ID!, content: String!): Comment!
}

# Input types dla mutations
input CreateUserInput {
  name: String!
  email: String!
  bio: String
}

input UpdateUserInput {
  name: String
  email: String
  bio: String
}

input CreatePostInput {
  title: String!
  content: String!
}

Mutations – modifying data

# Creating new user
mutation CreateUser {
  createUser(input: {
    name: "Jane Smith"
    email: "jane@example.com"
    bio: "Product Manager"
  }) {
    id
    name
    email
  }
}

# Creating post i returning author info
mutation CreatePost {
  createPost(input: {
    title: "GraphQL Introduction"
    content: "GraphQL is amazing..."
  }) {
    id
    title
    publishedAt
    author {
      name
      email
    }
  }
}

# Multiple mutations w single request
mutation MultipleOperations {
  createUser(input: { name: "Alice", email: "alice@example.com" }) {
    id
  }
  
  createPost(input: { title: "Hello World", content: "My first post" }) {
    id
  }
}

GraphQL vs REST – detailed comparison

Zalety GraphQL

AspektGraphQLREST
Data FetchingPrecise – request exactly what you needFixed endpoints – often over/under-fetch
Network RequestsSingle request for complex dataMultiple requests for related data
VersioningNo versioning needed – schema evolutionAPI versioning required
Type SafetyStrong typing w schemaNo built-in type system
DocumentationSelf-documenting schemaRequires external documentation
Real-timeBuilt-in subscriptionsRequires WebSockets/SSE setup

Wady GraphQL

ProblemGraphQLREST
Learning CurveSteeper – new concepts to learnWell-known patterns
CachingComplex – can’t use HTTP cachingSimple HTTP caching
File UploadsNot built-in, requires workaroundsNative HTTP multipart support
PerformanceQuery complexity analysis neededPredictable performance
ToolingGrowing ecosystem (2017)Mature tooling

Implementation considerations

GraphQL challenges

// Problem 1: N+1 query problem
// This query could generate many database calls:
/*
query {
  posts {           // 1 SQL query dla posts
    title
    author {        // N SQL queries dla każdego author!
      name
    }
  }
}
*/

// Solution: DataLoader pattern (batching i caching)
const authorLoader = new DataLoader(async (authorIds) => {
  // Single SQL query for all authors
  return await db.authors.findByIds(authorIds);
});

// Problem 2: Query complexity attacks
/*
query MaliciousQuery {
  posts {
    comments {
      author {
        posts {
          comments {
            author {
              posts {    // Infinitely deep!
                ...
              }
            }
          }
        }
      }
    }
  }
}
*/

// Solution: Query depth limiting i complexity analysis
const depthLimit = require('graphql-depth-limit');
const server = new GraphQLServer({
  validationRules: [depthLimit(7)]  // Max 7 levels deep
});

When to choose GraphQL vs REST

Choose GraphQL when:
• Mobile apps (bandwidth optimization)
• Complex data relationships
• Rapid frontend development
• Multiple client types (web, mobile, desktop)
• Real-time features needed
Choose REST when:
• Simple CRUD operations
• File uploads/downloads
• HTTP caching important
• Team unfamiliar z GraphQL
• Legacy system integration

GraphQL ecosystem (2017 perspective)

Popular GraphQL tools i libraries

// Server-side (Node.js)
// 1. GraphQL.js (reference implementation)
const { graphql, buildSchema } = require('graphql');

// 2. Apollo Server (most popular)
const { ApolloServer } = require('apollo-server');

// 3. GraphQL Yoga (by Prisma)
const { GraphQLServer } = require('graphql-yoga');

// Client-side
// 1. Apollo Client (React/Angular/Vue)
import { ApolloClient, gql, useQuery } from '@apollo/client';

// 2. Relay (Facebook's client)
// More complex but optimized for React

// 3. GraphQL Request (simple client)
import { request } from 'graphql-request';

// Tools
// 1. GraphiQL - in-browser IDE
// 2. GraphQL Playground - improved GraphiQL
// 3. Prisma - database toolkit z GraphQL

Czy GraphQL zastąpi REST całkowicie?

Nie całkowicie. GraphQL i REST będą coexist – każdy ma swoje use cases. GraphQL lepszy dla complex data fetching, REST prostszy dla simple CRUD i scenarios gdzie HTTP caching jest crucial.

Jak działa caching w GraphQL?

GraphQL can’t use HTTP caching jak REST. Używa application-level caching (Apollo Client cache, Redis) i normalization. Apollo Client provides intelligent caching based na object IDs.

Czy GraphQL jest trudniejszy od REST?

Initial learning curve jest steeper – nowe concepts jak schema, resolvers, query language. Ale once you understand basics, development może być faster dzięki strong typing i tooling.

Jak obsłużyć authentication w GraphQL?

Similar do REST – używaj HTTP headers (JWT tokens), context w resolvers. GraphQL doesn’t define auth mechanism – można używać existing solutions jak OAuth, JWT, sessions.

Czy GraphQL jest szybszy od REST?

Depends na use case. GraphQL może być faster dla complex data (fewer network requests), ale slower dla simple queries (query parsing overhead). Performance depends na implementation quality.

🚀 Zadanie dla Ciebie

Porównaj GraphQL z REST w praktyce:

  1. Design API dla blog system (users, posts, comments)
  2. REST version: Define endpoints i response formats
  3. GraphQL version: Create schema i example queries
  4. Mobile scenario: Compare data fetching dla user dashboard
  5. Analysis: Count network requests, data size, complexity

Measure developer experience: time to implement, ease of changes, documentation quality.

Przydatne zasoby:

Rozważasz GraphQL dla swoich projektów? Które zalety GraphQL wydają ci się najbardziej przekonujące w porównaniu z REST API?

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Przewijanie do góry