본문으로 건너뛰기
Previous
Next
API Design Complete Guide

API Design Complete Guide

API Design Complete Guide

이 글의 핵심

Compare features and pros/cons of REST API, GraphQL, and gRPC. Detailed explanation of use cases, performance, and developer experience for each API style with project-specific selection criteria.

Introduction: Importance of API Design

”Which API Style Should I Choose?”

In backend development, API design is one of the most important decisions. Choosing between REST, GraphQL, and gRPC greatly affects developer experience, performance, and maintainability. What This Guide Covers:

  • Core concepts of REST, GraphQL, and gRPC
  • Pros and cons of each API style
  • Performance comparison
  • Selection criteria by project

Table of Contents

  1. REST API
  2. GraphQL
  3. gRPC
  4. Comparative Analysis
  5. Selection Guide
  6. Summary

1. REST API

What is REST?

REST (Representational State Transfer) is an architectural style based on HTTP. Core Principles of REST:

graph TB
    A[REST Principles] --> B[Resource]
    A --> C[HTTP Methods]
    A --> D[Stateless]
    A --> E[Cacheable]
    
    B --> B1[Identified by URI]
    C --> C1[GET POST PUT DELETE]
    D --> D1[Server does not store state]
    E --> E1[Utilize HTTP cache]

REST API Example

Endpoint Design:

GET    /api/users          # List users
GET    /api/users/123      # Get specific user
POST   /api/users          # Create user
PUT    /api/users/123      # Update user
DELETE /api/users/123      # Delete user
GET    /api/users/123/posts  # User's post list

Node.js Express Implementation:

const express = require('express');
const app = express();
app.use(express.json());
// List users
app.get('/api/users', (req, res) => {
  const users = [
    { id: 1, name: 'Alice', email: '[email protected]' },
    { id: 2, name: 'Bob', email: '[email protected]' }
  ];
  res.json(users);
});
// Get specific user
app.get('/api/users/:id', (req, res) => {
  const user = { id: req.params.id, name: 'Alice' };
  res.json(user);
});
// Create user
app.post('/api/users', (req, res) => {
  const newUser = req.body;
  res.status(201).json(newUser);
});
app.listen(3000);

REST Pros and Cons

Pros:

  • Simplicity: Uses HTTP standard
  • Caching: Can utilize HTTP cache
  • Tool support: Postman, curl, etc.
  • Low learning curve: Intuitive Cons:
  • Over-fetching: Receives unnecessary data too
  • Under-fetching: Multiple requests needed (N+1 problem)
  • Version management: /api/v1/, /api/v2/
  • Lack of flexibility: Add endpoints when client requirements change

2. GraphQL

What is GraphQL?

GraphQL is a query language developed by Facebook, allowing clients to request exactly the data they need. GraphQL Structure:

graph LR
    A[Client] -->|Query| B[GraphQL Server]
    B -->|Only exact data| A
    
    C[REST] -->|Fixed response| D[Client]
    D -->|Receives unnecessary data too| C

GraphQL Example

Schema Definition:

# schema.graphql
type User {
  id: ID!
  name: String!
  email: String!
  posts: [Post!]!
}
type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
}
type Query {
  user(id: ID!): User
  users: [User!]!
  post(id: ID!): Post
}
type Mutation {
  createUser(name: String!, email: String!): User!
  updateUser(id: ID!, name: String): User!
  deleteUser(id: ID!): Boolean!
}

Query Example:

# Query user and posts at once
query {
  user(id: "123") {
    name
    email
    posts {
      title
      content
    }
  }
}
# Response (only needed fields)
{
  "data": {
    "user": {
      "name": "Alice",
      "email": "[email protected]",
      "posts": [
        {
          "title": "First Post",
          "content": "Content..."
        }
      ]
    }
  }
}

Node.js Apollo Server Implementation:

const { ApolloServer, gql } = require('apollo-server');
// Type definitions
const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
  }
  
  type Query {
    users: [User!]!
    user(id: ID!): User
  }
`;
// Resolvers
const resolvers = {
  Query: {
    users: () => [
      { id: '1', name: 'Alice', email: '[email protected]' },
      { id: '2', name: 'Bob', email: '[email protected]' }
    ],
    user: (_, { id }) => {
      return { id, name: 'Alice', email: '[email protected]' };
    }
  }
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

GraphQL Pros and Cons

Pros:

  • Exact data: Request only needed fields
  • Single endpoint: All requests through one /graphql
  • Type system: Type guarantee with schema
  • Developer experience: GraphQL Playground, automatic documentation Cons:
  • Complexity: High learning curve
  • Caching difficulty: Limited HTTP cache utilization
  • N+1 problem: Need additional tools like DataLoader
  • Overhead: Excessive for simple CRUD

3. gRPC

What is gRPC?

gRPC is a high-performance RPC (Remote Procedure Call) framework developed by Google. Uses Protocol Buffers to serialize data. gRPC Structure:

graph LR
    A[Client] -->|Binary Protobuf| B[gRPC Server]
    B -->|Binary Protobuf| A
    
    C[REST] -->|JSON Text| D[Server]
    D -->|JSON Text| C

gRPC Example

Protobuf Definition:

// user.proto
syntax = "proto3";
package user;
service UserService {
  rpc GetUser (GetUserRequest) returns (User);
  rpc ListUsers (ListUsersRequest) returns (ListUsersResponse);
  rpc CreateUser (CreateUserRequest) returns (User);
}
message User {
  int32 id = 1;
  string name = 2;
  string email = 3;
}
message GetUserRequest {
  int32 id = 1;
}
message ListUsersRequest {
  int32 page = 1;
  int32 page_size = 2;
}
message ListUsersResponse {
  repeated User users = 1;
}
message CreateUserRequest {
  string name = 1;
  string email = 2;
}

C++ Server Implementation:

#include <grpcpp/grpcpp.h>
#include "user.grpc.pb.h"
class UserServiceImpl final : public user::UserService::Service {
  grpc::Status GetUser(
      grpc::ServerContext* context,
      const user::GetUserRequest* request,
      user::User* response) override {
    
    response->set_id(request->id());
    response->set_name("Alice");
    response->set_email("[email protected]");
    
    return grpc::Status::OK;
  }
};
int main() {
  std::string server_address("0.0.0.0:50051");
  UserServiceImpl service;
  
  grpc::ServerBuilder builder;
  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  builder.RegisterService(&service);
  
  std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
  std::cout << "Server listening on " << server_address << std::endl;
  server->Wait();
  
  return 0;
}

gRPC Pros and Cons

Pros:

  • High performance: Binary protocol, HTTP/2
  • Type safety: Protobuf schema
  • Streaming: Bidirectional streaming support
  • Multi-language support: Generate clients in multiple languages Cons:
  • Limited browser support: Needs gRPC-Web
  • Debugging difficulty: Binary protocol
  • Learning curve: Protobuf syntax
  • Tool shortage: Cannot use REST tools like Postman

4. Comparative Analysis

Comprehensive Comparison Table

FeatureRESTGraphQLgRPC
ProtocolHTTP/1.1HTTP/1.1HTTP/2
Data FormatJSONJSONProtobuf (Binary)
Type SystemNoneYes (Schema)Yes (Protobuf)
CachingExcellent (HTTP)LimitedLimited
PerformanceMediumMediumFast
Learning CurveLowMediumHigh
Browser SupportExcellentExcellentLimited
StreamingNoneSubscriptionBidirectional

Performance Benchmark

Test Environment: 100,000 requests, average response size 1KB

Throughput (requests/sec):
1. gRPC:     50,000  ⭐
2. REST:     20,000
3. GraphQL:  15,000
Response Time (ms):
1. gRPC:     2ms   ⭐
2. REST:     5ms
3. GraphQL:  7ms
Data Size (1000 objects):
1. Protobuf: 82KB  ⭐
2. JSON:     120KB

Use Case Comparison

REST Suitable For:

  • Simple CRUD API
  • Public API (external developer use)
  • When caching is important
  • Legacy system integration GraphQL Suitable For:
  • Complex data requirements
  • Mobile apps (data savings)
  • Fast frontend development
  • Various clients (web, mobile, desktop) gRPC Suitable For:
  • Microservice communication
  • Real-time streaming
  • High performance requirements
  • Internal API (browser not needed)

5. Selection Guide

Selection Flowchart

flowchart TD
    A[Start API Design] --> B{Browser Client?}
    B -->|No| C{Performance Top Priority?}
    C -->|Yes| D[gRPC]
    C -->|No| E[REST]
    
    B -->|Yes| F{Complex Data Requirements?}
    F -->|Yes| G[GraphQL]
    F -->|No| H{Public API?}
    H -->|Yes| I[REST]
    H -->|No| J[GraphQL or REST]

Recommendations by Project

1. Startup MVP

  • REST: Fast development, simplicity
  • Example: Express + MongoDB 2. Mobile App Backend
  • GraphQL: Data savings, flexibility
  • Example: Apollo Server + PostgreSQL 3. Microservices
  • gRPC: High performance, type safety
  • Example: gRPC + Kubernetes 4. Public API
  • REST: Standard, tool support
  • Example: Stripe API, GitHub API 5. Real-time App
  • GraphQL Subscription or gRPC Streaming
  • Example: Chat, notifications, dashboard

Hybrid Approach

Many projects mix multiple API styles.

Frontend (Browser)
    ↓ GraphQL
API Gateway
    ↓ gRPC
Microservices

Example:

  • External clients: REST or GraphQL
  • Internal services: gRPC
  • Real-time features: WebSocket or GraphQL Subscription

Implementation Patterns

REST + gRPC Hybrid:

// API Gateway (Express + REST)
app.get('/api/users/:id', async (req, res) => {
  // Call internal gRPC service
  const user = await grpcClient.getUser({ id: req.params.id });
  res.json(user);
});

GraphQL + gRPC Hybrid:

// GraphQL resolver calling gRPC
const resolvers = {
  Query: {
    user: async (_, { id }) => {
      // Call gRPC service
      return await grpcClient.getUser({ id });
    }
  }
};

6. Summary

Key Summary

REST:

  • HTTP-based, resource-centric
  • Simple and excellent caching
  • Suitable for public APIs GraphQL:
  • Query language, client-centric
  • Exact data requests
  • Suitable for complex data requirements gRPC:
  • Binary protocol, high performance
  • Type safety, streaming
  • Suitable for microservices

Selection Criteria

PriorityChoice
SimplicityREST
FlexibilityGraphQL
PerformancegRPC
Public APIREST
MobileGraphQL
MicroservicesgRPC

Next Steps

For detailed implementation methods of each API style, refer to these guides:

Additional Learning Resources

Official Documentation:

Quick Decision Guide

Simple CRUD? → REST
Complex data fetching? → GraphQL
High performance internal? → gRPC
Public API? → REST
Mobile app? → GraphQL
Microservices? → gRPC
Real-time bidirectional? → gRPC or GraphQL Subscription

Keywords

API, REST, GraphQL, gRPC, API Design, Backend, Microservices, HTTP, Protocol Buffers, Performance, Comparison


자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. Compare features and pros/cons of REST API, GraphQL, and gRPC. Detailed explanation of use cases, performance, and devel… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.


이 글에서 다루는 키워드 (관련 검색어)

API, REST, GraphQL, gRPC, Backend, API Design, Microservices 등으로 검색하시면 이 글이 도움이 됩니다.