JSON-RPC 2.0 명세

Dohyeop Kim·2023년 1월 2일
0
post-thumbnail

JSON-RPC 2.0 버전 명세서를 번역했습니다.
JSON-RPC는 JSON형식으로 된 통신규약으로써, 저는 비트코인, 이더리움 등 블록체인 클라이언트에서 제공하는 JSON-RPC API를 통해서 처음 접했습니다.

원문은 다음 링크에서 확인하실 수 있습니다.

JSON-RPC 2.0 Specification

Origin Date: 2010-03-26 (based on the 2009-05-24 version)

Updated: 2013-01-04

Author: JSON-RPC Working Group json-rpc@googlegroups.com

번역: dohp.kim@gmail.com

목차
  1. 개요
  2. 문서 범례
  3. 호환성
  4. 요청 객체
    4.1 통보기능
    4.2 params 의 구조
  5. 응답 객체
    5.1 에러 객체
  6. 일괄처리
  7. 예제s
  8. 확장

1 개요

JSON-RPC 는 상태를 관리하지 않는(stateless) 가볍게 사용 할 수 있는 원격 프로시저 호출 프로토콜 입니다(RPC; Remote Procedure Call). 이 문서는 JSON-RPC 의 구조와 작동
규칙에 대해서 정의합니다. JSON-RPC 는 구체적인 기술에 의존하지 않고 소켓(socket), HTTP 그리고 다양한 네트워크 기술에 적용될 수 있는 통신 규약입니다.
단지 자료를 표현하는 수단으로 JSON(RFC4627)
을 사용합니다.

심플하게 사용하세요!

It is designed to be simple!

2 문서 범례

강조된 키워드 “반드시(MUST, REQUIRED, SHALL)”, “권장(SHOULD, RECOMMENDED)”, “선택(MAY, OPTIONAL)” 는 RFC 2119 에 정의된 용례로 사용되었습니다.

JSON-RPC 는 JSON 을 사용하므로, 데이터의 타입(자료형) 역시 JSON 타입 시스템을 그대로 사용합니다(https://www.json.org 혹은 RFC4627 참조).
JSON 은 4 가지 원시타입(Strings, Numbers, Booleans, Null)을 표현
할 수 있으며 두 가지의 객체 타입(Object, Array)을 지원합니다. 이 문서에서의 “원시타입” 이란 용어는 항상 JSON 원시타입을 의미하며, 이 문서에서의 “객체타입” 용어는 항상 JSON 의 객체 타입을
의미합니다.

이 문서의 예제에서 나오는 모든 식별자 이름들은 대소문자를 구분하여 작동되는것으로 가정했습니다. 함수, 메소드, 프로시저 용어들은 혼용하여 사용했습니다.

이 문서에서 언급된 클라이언트는, 요청객체의 출처(origin)이고 응답객체를 처리하는 주체입니다.

이 문서에서 언급된 서버는, 응답객체의 출처(origin)이고 요청객체를 처리하는 주체입니다.

하나의 구현체가 클라이언트와 서버의 역할을 모두 수행할 수 있으며, 서로 다른 여러 개의 클라이언트 혹은 하나의 클라이언트의 요청을 동시에 처리할 수 있습니다. 문서에는 이러한 계층의 복잡성에 대해선 언급하지 않습니다.

3 호환성

JSON-RPC 2.0 버전의 요청, 응답 형식은 1.0 버전을 사용하는 API 와 호환이 되지 않을 수 도 있습니다. 버전 식별은 “jsonrpc” 라는 키에 “2.0” 값이 들어있는 경우 버전 2.0 으로
간단하게 식별 할 수 있습니다. 버전 2.0 을 사용하는 API 를 설계하실 때, 버전 1.0 도 지원하는 방안을 고려해주십시오.

4 요청 객체

원격 프로시저 호출은 서버에 요청 객체를 전송함으로써 시작합니다. 요청 객체는 아래와 같은 필드를 가지고 있습니다:

jsonrpc

JSON-RPC 의 버전을 나타내는 문자열 타입입니다. 반드시 “2.0” 값을 가져야 합니다.

method

호출하려는 메소드의 이름을 나타내는 문자열 타입입니다. “rpc" 와 마침표(U+002E or ASCII 46)로 시작되는 메소드명(rpc.)은 서버 내부적으로 사용될 목적의 예약어 이므로, 이 문자열로 시작하는 메소드를 다른 목적으로 사용하는 것은 반드시 피해야
합니다.

params

호출한 메소드에서 사용될 파라미터들을 나타내는 객채타입 입니다. 이는 선택적 이므로 누락될 수 도 있습니다.

id

해당 필드는 클라이언트에서 생성한 식별자이며 반드시 문자열, 숫자, Null 타입 중 하나여야 합니다. 서버는 응답 객체의 id 필드에 요청 객체에 있는 값과 동일한 값을 반드시 포함해야 합니다.

이 필드가 있는 경우:

Null 을 사용하지 않는게 권장됩니다. 버전 2.0 에서는 통보기능을 사용하기 위해 이 필드 자체를 삭제하지만, 버전 1.0 인 경우 이 필드에 Null 을 할당합니다. 따라서 두 버전 모두를 지원하는 API
에서는 통지기능을 구분하기가 복잡해 질 수 있습니다. 그리고 만약 그 값이 숫자 타입이라면 소수점을 피하는 것이 권장됩니다.

이 필드가 없는 경우(값이 Null 이라는 의미가 아니며, id 라는 키 자체가 없음):

해당 요청은 통보(Notification) 기능을 하는 요청으로 간주 합니다.

4.1 통보기능

통보기능은 “id” 키 자체가 누락된 요청 객체를 의미합니다.

통보기능은 원격 호출한 클라이언트가 응답 데이터에 대하여 관심이 없거나 혹은 필요치 않은 경우에 사용합니다.

따라서 서버는 통보기능 요청에 대해서 반드시 응답을 하지 말아야 합니다.

응답을 받지 않으므로 클라이언트 쪽에서는 해당 호출의 결과가 성공인지 실패인지 알 수 없다는 점을 유의해야 합니다.

4.2 params 의 구조

만약 params 이 포함된 요청 객체라면 그 타입은 반드시 2 가지 객체 타입 중 한 가지 방식으로만 제공 되어야 합니다.

배열 방식(by-position):

호출하는 메소드가 원하는 순서로 반드시 인자를 전달해야 합니다.

키-값 방식(by-name):

호출하는 메소드가 원하는 인자의 이름과 값이 매핑되어 있어야 합니다.

특정 인자가 누락된 경우 서버는 해당 호출을 실패시킬 수 있습니다.

키는 반드시 대소문자를 구분하여 식별되어야 합니다.

5 응답 객체

요청 객체를 수신한 서버는 통보기능을 제외한 모든 요청에 반드시 응답해야만 합니다. 응답 객체는 아래의 필드를 가지고 있습니다.

jsonrpc

JSON-RPC 의 버전을 나타내는 문자열 타입입니다. 반드시 “2.0” 값을 가져야 합니다.

result

성공 응답인 경우 이 필드가 반드시 있어야 합니다.

실패 응답인 경우 이 필드가 반드시 없어야 합니다.

필드의 값은 요청된 메소드가 결정합니다.

error

성공 응답인 경우 이 필드가 반드시 없어야 합니다.

실패 응답인 경우 이 필드가 반드시 있어야 합니다.

이 필드의 값 타입은 반드시 5.1 에러 객체 이어야 합니다.

id

이 필드는 반드시 있어야 합니다.

요청 객체의 “id” 값과 반드시 같은 값을 입력해야 합니다.

만약 요청 메소드가 실패했을 경우 반드시 Null 값을 입력해야 합니다.

모든 응답 객체는 result 혹은 error 둘 중 하나를 반드시 포함해야 합니다. 즉, 이 두 개의 필드는 하나의 응답 객체에 반드시 공존해서는 안됩니다.

5.1 에러 객체

원격 호출된 메소드가 실패한 경우, 응답 객체의 “error” 키에 아래의 필드들을 가지는 객체를 반드시 할당하여 응답해야 합니다.

code

에러의 타입을 정의하는 숫자.

반드시 정수 타입을 사용해야 합니다.

message

에러를 설명하는 문자열.

하나의 문장으로 끝맺는 것을 권장 합니다.

data

에러 해석에 도움이 되는 원시타입 혹은 객체타입의 추가적인 정보입니다.

이 필드는 누락되어도 됩니다.

이 필드의 값은 서버 애플리케이션에서 자유롭게 정의 할 수 있습니다.

필드 “code” 의 값 중에서 -32768 ~ -32000 범위의 정수는 예약되어 있습니다. 아래 표에서 사용되지 않은 숫자라도 추후에 프로토콜에 정의될 수 있으므로 임의로 사용해서는 안됩니다. 에러 코드의
스키마는 XML-RPC 에서 사용되는 것과 매우 유사합니다. 아래 링크에서 확인 할 수 있습니다:

http://xmlrpcepi.sourceforge.net/specs/rfc.fault_codes.php

codemessagedata
-32700Parse error요청 객체의 JSON 포맷 자체에 오타가 있어서 서버에서 파싱 실패
-32600Invalid Request요청 객체가 올바른 JSON 포맷이긴 하나, JSON-RPC 의 규격을 만족하진 못함
-32601Method not found요청 객체가 호출한 메소드 이름이 존재하지 않거나 틀린 경우
-32602Invalid params요청 객체가 호출한 메소드가 원하는 파라미터들을 충족하지 못함
-32603Internal error서버 내부 오류
-32000 to -32099Server error서버 내부 오류를 다양하게 정의하기 위해서 예약되어 있음

6 일괄처리

여러 요청을 일괄처리 하기 위하여, 클라이언트는 요청 객체를 배열에 담아서 서버로 전송 하는 방식을 선택 할 수 있습니다.

서버는 해당 배열에 담겨있는 요청 객체들을 모두 처리한 뒤에 응답 객체들이 담긴 배열을 응답해야 합니다. 서버는 배열에 담겨있던 각각의 요청 객체들과 일대일로 쌍을 이루는 응답 객체들을 빠짐없이(통보기능은 제외)
생성하여 배열에 담아 응답하는 것이 권장됩니다. 서버는 일괄처리에 담긴 여러 요청들을 병렬처리 할 수 도 있으며, 이때 처리 순서는 서버가 정의합니다.

따라서 일괄처리 응답 배열에 담긴 응답 객체들의 순서는 클라이언트가 요청 했던 순서를 보장하지 않으며, 클라이언트가 각각의 응답 객체에 존재하는 “id” 값을 사용하여 고유하게 식별하고 선별하는 것이 권장 됩니다.

만약 전송받은 일괄처리 요청이 잘못된 JSON 포맷이거나(에러코드 -32700) 배열에 요청 객체가 전혀 없는 경우, 서버는 배열이 아니라 반드시 단 한개의 응답 객체로 응답해야 합니다.

만약 일괄처리 요청이 제대로 처리됬지만 그 요청들이 전부 통보기능이라서 응답 객체를 만들어서는 안되는 경우, 서버는 빈 배열을 응답해서는 안되고 반드시 응답 자체를 하지 않아야 합니다.

7 예제

Syntax:

--> data sent to Server
<-- data sent to Client

배열방식 params 사용한 경우:

--> {
  "jsonrpc": "2.0",
  "method": "subtract",
  "params": [
    42,
    23
  ],
  "id": 1
}
<-- {
  "jsonrpc": "2.0",
  "result": 19,
  "id": 1
}

--> {
  "jsonrpc": "2.0",
  "method": "subtract",
  "params": [
    23,
    42
  ],
  "id": 2
}
<-- {
  "jsonrpc": "2.0",
  "result": -19,
  "id": 2
}

키-값 방식 params 사용한 경우:

--> {
  "jsonrpc": "2.0",
  "method": "subtract",
  "params": {
    "subtrahend": 23,
    "minuend": 42
  },
  "id": 3
}
<-- {
  "jsonrpc": "2.0",
  "result": 19,
  "id": 3
}

--> {
  "jsonrpc": "2.0",
  "method": "subtract",
  "params": {
    "minuend": 42,
    "subtrahend": 23
  },
  "id": 4
}
<-- {
  "jsonrpc": "2.0",
  "result": 19,
  "id": 4
}

통보기능 호출:

--> {
  "jsonrpc": "2.0",
  "method": "update",
  "params": [
    1,
    2,
    3,
    4,
    5
  ]
}
<-- // 통보기능 호출이므로 서버는 응답해서는 안됨
--> {
  "jsonrpc": "2.0",
  "method": "foobar"
}
<-- // 통보기능 호출이므로 서버는 응답해서는 안됨

존재하지 않는 메소드이거나 메소드 이름에서 오타가 있는 요청인 경우:

--> {
  "jsonrpc": "2.0",
  "method": "foobar",
  "id": "1"
}
<-- {
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "Method not found"
  },
  "id": "1"
}

JSON 포맷 자체가 틀린 요청인 경우:

--> {
  "jsonrpc": "2.0",
  "method": "foobar, "
  params
  ": "
  bar
  ", "
  baz
]
  <-- {
  "jsonrpc": "2.0",
  "error": {
    "code": -32700,
    "message": "Parse error"
  },
  "id": null
}

규약 불충족한 요청인 경우(method 의 값은 문자열만 허용):

--> {
  "jsonrpc": "2.0",
  "method": 1,
  "params": "bar"
}
<-- {
  "jsonrpc": "2.0",
  "error": {
    "code": -32600,
    "message": "Invalid Request"
  },
  "id": null
}

일괄처리 요청 - JSON 포맷 자체가 틀린 경우:

--> [
  {
    "jsonrpc": "2.0",
    "method": "sum",
    "params": [
      1,
      2,
      4
    ],
    "id": "1"
  },
  {
    "jsonrpc": "2.0",
    "method"
  ]
    <--
  {
    "jsonrpc": "2.0",
    "error": {
      "code": -32700,
      "message": "Parse error"
    },
    "id": null
  }

일괄처리 요청 - 규약 불충족(빈 배열로 요청함):

--> []
<-{
  "jsonrpc": "2.0",
  "error": {
    "code": -32600,
    "message": "Invalid Request"
  },
  "id": null
}

일괄처리 요청 - 규약 불충족:

--> [
  1
]
<-- [
  {
    "jsonrpc": "2.0",
    "error": {
      "code": -32600,
      "message": "Invalid Request"
    },
    "id": null
  }
]

일괄처리 요청 - 규약 불충족:

--> [
  1,
  2,
  3
]
<-- [
  {
    "jsonrpc": "2.0",
    "error": {
      "code": -32600,
      "message": "Invalid Request"
    },
    "id": null
  },
  {
    "jsonrpc": "2.0",
    "error": {
      "code": -32600,
      "message": "Invalid Request"
    },
    "id": null
  },
  {
    "jsonrpc": "2.0",
    "error": {
      "code": -32600,
      "message": "Invalid Request"
    },
    "id": null
  }
]

일괄처리 요청:

--> [
  {
    "jsonrpc": "2.0",
    "method": "sum",
    "params": [
      1,
      2,
      4
    ],
    "id": "1"
  },
  {
    "jsonrpc": "2.0",
    "method": "notify_hello",
    "params": [
      7
    ]
  },
  {
    "jsonrpc": "2.0",
    "method": "subtract",
    "params": [
      42,
      23
    ],
    "id": "2"
  },
  {
    "foo": "boo"
  },
  {
    "jsonrpc": "2.0",
    "method": "foo.get",
    "params": {
      "name": "myself"
    },
    "id": "5"
  },
  {
    "jsonrpc": "2.0",
    "method": "get_data",
    "id": "9"
  }
]
<-- [
  {
    "jsonrpc": "2.0",
    "result": 7,
    "id": "1"
  },
  {
    "jsonrpc": "2.0",
    "result": 19,
    "id": "2"
  },
  {
    "jsonrpc": "2.0",
    "error": {
      "code": -32600,
      "message": "Invalid Request"
    },
    "id": null
  },
  {
    "jsonrpc": "2.0",
    "error": {
      "code": -32601,
      "message": "Method not found"
    },
    "id": "5"
  },
  {
    "jsonrpc": "2.0",
    "result": [
      "hello",
      5
    ],
    "id": "9"
  }
]

일괄처리 요청 (all notifications):

--> [
  {
    "jsonrpc": "2.0",
    "method": "notify_sum",
    "params": [
      1,
      2,
      4
    ]
  },
  {
    "jsonrpc": "2.0",
    "method": "notify_hello",
    "params": [
      7
    ]
  }
]
<-- // 일괄처리 요청의 모든 요청이 통보기능이므로 응답 자체를 해서는 안됨

8 확장

“rpc.” 으로 시작되는 메소드 이름은 시스템을 위한 예약어 이므로 반드시 다른 용도로 사용되어서는 안됩니다.


Copyright (C) 2007-2010 by the JSON-RPC Working Group

This document and translations of it may be used to implement JSON-RPC, it may be copied and furnished to others, and
derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied,
published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright
notice and this paragraph are included on all such copies and derivative works. However, this document itself may not
bemodified in any way.

The limited permissions granted above are perpetual and will not be revoked.

This document and the information contained herein is provided "AS IS" and ALL WARRANTIES, EXPRESS OR IMPLIED are
DISCLAIMED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY
RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

profile
맘마가 먹고십흔 고양이

0개의 댓글