JSON ν¬λ§·μ μ¬μ©νλ μ격 νλ‘μμ νΈμΆ(RPC) νλ‘ν μ½μ΄λ€. ν΄λΌμ΄μΈνΈκ°# μλ²μ λ©μλλ₯Ό λ§μΉ λ‘컬 ν¨μμ²λΌ νΈμΆν μ μκ² ν΄μ£Όλ κ²½λ ν΅μ κ·μ½μ΄λ€.
ν΅μ¬ νΉμ§: Transport-independent (μ μ‘ κ³μΈ΅ λ 립μ ) - HTTP, TCP, WebSocket λ± μ΄λ€ μ μ‘ νλ‘ν μ½ μμμλ λμ κ°λ₯νλ€.
ν΄λΉ κ°λ μ΄ νμν μ΄μ
- μ격 ν¨μ νΈμΆ νμ€ν: μλ‘ λ€λ₯Έ μμ€ν κ° ν¨μ νΈμΆμ μΌκ΄λ λ°©μμΌλ‘ μ²λ¦¬
- κ²½λ νλ‘ν μ½: XML-RPCμ λΉν΄ κ°κ²°ν JSON ν¬λ§·μΌλ‘ μ€λ²ν€λ κ°μ
- λΉλκΈ° μ²λ¦¬ μ§μ: μ¬λ¬ μμ²μ λμμ 보λ΄κ³ λΉλκΈ°λ‘ μλ΅ λ°κΈ° κ°λ₯
- μλ¦Ό κΈ°λ₯: μλ΅μ΄ νμ μλ μΌλ°©ν₯ ν΅μ μ§μ (Notification)
AS-IS
μ ν΅μ μΈ REST APIλ 리μμ€ μ€μ¬μ΄λ©°, κ° λμλ§λ€ URL μλν¬μΈνΈκ° νμνλ€.
// REST API λ°©μ: μλν¬μΈνΈλ§λ€ λ³λ URL
POST /api/users/create
POST /api/users/update
POST /api/users/delete
GET /api/users/list
GET /api/products/calculate-priceλ¬Έμ μ :
- URL κ΄λ¦¬ 볡μ‘λ μ¦κ°
- ν¨μ νΈμΆ μλ―Έκ° URLμ λΆμ°λ¨
- λ©μλ μ΄λ¦κ³Ό URL λ§€ν λΆμΌμΉ κ°λ₯
TO-BE
JSON-RPCλ λ¨μΌ μλν¬μΈνΈμμ λ©μλ μ΄λ¦μΌλ‘ ν¨μλ₯Ό νΈμΆνλ€.
// JSON-RPC λ°©μ: λ¨μΌ μλν¬μΈνΈμμ λ©μλ ꡬλΆ
POST /api/rpc
// λͺ¨λ νΈμΆμ΄ λμΌν ꡬ쑰
{"jsonrpc": "2.0", "method": "user.create", "params": {...}, "id": 1}
{"jsonrpc": "2.0", "method": "user.update", "params": {...}, "id": 2}
{"jsonrpc": "2.0", "method": "user.delete", "params": {...}, "id": 3}
{"jsonrpc": "2.0", "method": "product.calculatePrice", "params": {...}, "id": 4}κ°μ μ :
- λ¨μΌ μλν¬μΈνΈλ‘ λͺ¨λ ν¨μ νΈμΆ μ²λ¦¬
- λ©μλ μ΄λ¦μ΄ λͺ μμ μΌλ‘ λλ¬λ¨
- μΌκ΄λ μμ²/μλ΅ κ΅¬μ‘°
JSON-RPC λ©μμ§ 3κ°μ§ νμ
1. Request (μμ²)
ν΄λΌμ΄μΈνΈκ° μλ²μ λ©μλλ₯Ό νΈμΆν λ μ¬μ©νλ€.
{
"jsonrpc": "2.0",
"method": "subtract",
"params": {"minuend": 42, "subtrahend": 23},
"id": 3
}νμ νλ:
method: νΈμΆν λ©μλ μ΄λ¦ (λ¬Έμμ΄)id: μμ²-μλ΅ λ§€μΉμ μν μλ³μ (λ¬Έμμ΄ λλ μ μ)
μ ν νλ:
params: νλΌλ―Έν° (κ°μ²΄ λλ λ°°μ΄, μλ΅ κ°λ₯)jsonrpc: νλ‘ν μ½ λ²μ (2.0μμ νμ)
2. Response (μλ΅)
μλ²κ° μμ²μ λν κ²°κ³Όλ₯Ό λ°νν λ μ¬μ©νλ€.
{
"jsonrpc": "2.0",
"result": 19,
"id": 3
}μ±κ³΅ μ:
result: λ©μλ μ€ν κ²°κ³Όid: μλ μμ²μ id
μ€ν¨ μ:
{
"jsonrpc": "2.0",
"error": {
"code": -32600,
"message": "Invalid Request"
},
"id": null
}error: μ€λ₯ κ°μ²΄ (code, message νμ)id: μλ μμ²μ id (νμ± μ€ν¨ μ null)
3. Notification (μλ¦Ό)
μλ΅μ΄ νμ μλ μΌλ°©ν₯ λ©μμ§λ€. id νλλ₯Ό μλ΅νλ©΄ μλ²λ μλ΅νμ§ μλλ€.
{
"jsonrpc": "2.0",
"method": "update",
"params": [1, 2, 3, 4, 5]
}μ©λ:
- λ‘κ·Έ μ μ‘
- μ΄λ²€νΈ μλ¦Ό
- λ°±κ·ΈλΌμ΄λ μμ νΈλ¦¬κ±°
JSON-RPC ν΅μ νλ¦
sequenceDiagram autonumber participant Client as Client participant Server as Server Note over Client,Server: 1. μΌλ° μμ²/μλ΅ Client->>Server: Request<br/>{"method": "add", "params": [2, 3], "id": 1} Server->>Server: add(2, 3) μ€ν Server->>Client: Response<br/>{"result": 5, "id": 1} Note over Client,Server: 2. μλ¦Ό (μλ΅ μμ) Client->>Server: Notification<br/>{"method": "log", "params": ["info"]} Note over Server: log μ€ν, μλ΅ μμ Note over Client,Server: 3. λ°°μΉ μμ² (λΉλκΈ°) Client->>Server: Batch Request<br/>[{"method": "sum", "id": 1},<br/>{"method": "multiply", "id": 2}] Server->>Server: λ³λ ¬ μ²λ¦¬ Server->>Client: Batch Response<br/>[{"result": 10, "id": 1},<br/>{"result": 20, "id": 2}]
ν΅μ¬ νλ¦:
- ν΄λΌμ΄μΈνΈκ°
idμ ν¨κ» μμ² μ μ‘ - μλ²κ° λ©μλ μ€ν ν λμΌν
idλ‘ μλ΅ λ°ν - μλ¦Όμ
idμμ΄ μ μ‘λμ΄ μλ΅ μμ - λ°°μΉ μμ²μ μ¬λ¬ νΈμΆμ λ°°μ΄λ‘ λ¬Άμ΄ μ μ‘ κ°λ₯
λ²μ λ³ μ£Όμ μ°¨μ΄μ
Version 1.0 (2005)
// Request
{"method": "echo", "params": ["Hello"], "id": 1}
// Response
{"result": "Hello", "error": null, "id": 1}νΉμ§:
errorνλκ° νμ μ‘΄μ¬ (null κ°λ₯)jsonrpcλ²μ νλ μμ
Version 2.0 (2010, νμ¬ νμ€)
// Request
{"jsonrpc": "2.0", "method": "echo", "params": ["Hello"], "id": 1}
// Response (μ±κ³΅)
{"jsonrpc": "2.0", "result": "Hello", "id": 1}
// Response (μ€ν¨)
{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid"}, "id": 1}κ°μ μ :
jsonrpc: "2.0"νλλ‘ λ²μ λͺ μresultμerrorμ€ νλλ§ μ‘΄μ¬ (λ°°νμ )- Named parameters μ§μ (paramsλ₯Ό κ°μ²΄λ‘ μ λ¬)
- λ°°μΉ μμ² κ³΅μ μ§μ
μ¬μ μ μλ μ€λ₯ μ½λ
| Code | Message | μλ―Έ |
|---|---|---|
| -32700 | Parse error | JSON νμ± μ€ν¨ |
| -32600 | Invalid Request | μμ² κ΅¬μ‘°κ° μλͺ»λ¨ |
| -32601 | Method not found | λ©μλκ° μ‘΄μ¬νμ§ μμ |
| -32602 | Invalid params | νλΌλ―Έν°κ° μλͺ»λ¨ |
| -32603 | Internal error | μλ² λ΄λΆ μ€λ₯ |
μλ²λ³ μ€λ₯: -32000 ~ -32099 λ²μλ μλ²κ° μμ λ‘κ² μ μ κ°λ₯
Transport-Independent νΉμ±
JSON-RPCλ μ μ‘ κ³μΈ΅μ λ 립μ μ΄λ€. λ€μν νλ‘ν μ½ μμμ λμνλ€.
graph TB subgraph "JSON-RPC Protocol Layer" JSONRPC[JSON-RPC<br/>λ©μμ§ κ΅¬μ‘°] end subgraph "Transport Layer (μ ν κ°λ₯)" HTTP[HTTP/HTTPS] WS[WebSocket] TCP[TCP Socket] IPC[IPC/Unix Socket] end JSONRPC --> HTTP JSONRPC --> WS JSONRPC --> TCP JSONRPC --> IPC HTTP --> Network[λ€νΈμν¬ μ μ‘] WS --> Network TCP --> Network IPC --> Local[λ‘컬 νλ‘μΈμ€]
μμ:
- HTTP: μΉ APIλ‘ μ¬μ© (κ°μ₯ μΌλ°μ )
- WebSocket: μ€μκ° μλ°©ν₯ ν΅μ
- TCP: κ³ μ±λ₯ λ§μ΄ν¬λ‘μλΉμ€ κ° ν΅μ
- IPC: λ‘컬 νλ‘μΈμ€ κ° ν΅μ
JSON-RPC vs REST API
| νΉμ± | JSON-RPC | REST API |
|---|---|---|
| μ€μ¬ κ°λ | λ©μλ(ν¨μ) | 리μμ€ |
| μλν¬μΈνΈ | λ¨μΌ URL | 리μμ€λ³ URL |
| HTTP λ©μλ | μ£Όλ‘ POST | GET, POST, PUT, DELETE |
| μΊμ± | μ΄λ €μ | HTTP μΊμ± νμ© κ°λ₯ |
| λ°°μΉ μμ² | κΈ°λ³Έ μ§μ | λΉνμ€ |
| μλ¦Ό | κΈ°λ³Έ μ§μ | μμ |
JSON-RPCλ₯Ό μ ννλ κ²½μ°:
- RPC μ€νμΌμ APIκ° μμ°μ€λ¬μ΄ κ²½μ°
- λ°°μΉ μμ²μ΄ νμν κ²½μ°
- λ΄λΆ λ§μ΄ν¬λ‘μλΉμ€ ν΅μ
- LSP κ°μ νλ‘ν μ½ κ³μΈ΅μ΄ νμν κ²½μ°