Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ
Что такое JSON-RPC
JSON-RPC — это лёгкий протокол удалённого вызова процедур (RPC), использующий JSON для кодирования данных. Он позволяет клиентам вызывать методы на удалённом сервере через HTTP, WebSocket или другие транспорты, отправляя JSON-запросы и получая JSON-ответы.
Основная структура JSON-RPC 2.0
Запрос:
{
"jsonrpc": "2.0",
"method": "add",
"params": [5, 3],
"id": 1
}
Ответ (успех):
{
"jsonrpc": "2.0",
"result": 8,
"id": 1
}
Ответ (ошибка):
{
"jsonrpc": "2.0",
"error": {
"code": -32600,
"message": "Invalid Request"
},
"id": 1
}
Мой опыт использования JSON-RPC
Да, я использовал JSON-RPC в своей практике. Вот основные сценарии:
1. Blockchain приложения (Ethereum, Bitcoin)
JSON-RPC широко используется в blockchain экосистеме. Например, взаимодействие с Ethereum nodes:
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
public class EthereumRPCClient {
private static final String ETHEREUM_RPC_URL = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID";
private final HttpClient httpClient = HttpClient.newHttpClient();
private final ObjectMapper objectMapper = new ObjectMapper();
public String getBalance(String address) throws Exception {
String request = objectMapper.writeValueAsString(new JsonRpcRequest(
"2.0",
"eth_getBalance",
new Object[]{address, "latest"},
1
));
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(java.net.URI.create(ETHEREUM_RPC_URL))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(request))
.build();
HttpResponse<String> response = httpClient.send(
httpRequest,
HttpResponse.BodyHandlers.ofString()
);
JsonNode result = objectMapper.readTree(response.body());
return result.get("result").asText();
}
}
class JsonRpcRequest {
public String jsonrpc;
public String method;
public Object[] params;
public int id;
public JsonRpcRequest(String jsonrpc, String method, Object[] params, int id) {
this.jsonrpc = jsonrpc;
this.method = method;
this.params = params;
this.id = id;
}
}
2. WebSocket связь между микросервисами
JSON-RPC удобен для real-time коммуникации:
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class JsonRpcWebSocketHandler extends TextWebSocketHandler {
private final ObjectMapper objectMapper = new ObjectMapper();
private final RpcMethodDispatcher methodDispatcher;
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message)
throws Exception {
JsonRpcRequest request = objectMapper.readValue(
message.getPayload(),
JsonRpcRequest.class
);
try {
Object result = methodDispatcher.invoke(request.method, request.params);
JsonRpcResponse response = new JsonRpcResponse(
"2.0",
result,
null,
request.id
);
session.sendMessage(new TextMessage(
objectMapper.writeValueAsString(response)
));
} catch (Exception e) {
JsonRpcError error = new JsonRpcError(-32603, e.getMessage());
JsonRpcResponse errorResponse = new JsonRpcResponse(
"2.0",
null,
error,
request.id
);
session.sendMessage(new TextMessage(
objectMapper.writeValueAsString(errorResponse)
));
}
}
}
3. Интеграция с внешними API
Некоторые сервисы предоставляют JSON-RPC API (Bitcoin Core, некоторые Solana RPC endpoints):
public class BitcoinRPCClient {
private final String rpcUrl;
private final String username;
private final String password;
private final HttpClient httpClient = HttpClient.newHttpClient();
private final ObjectMapper objectMapper = new ObjectMapper();
public BitcoinRPCClient(String rpcUrl, String username, String password) {
this.rpcUrl = rpcUrl;
this.username = username;
this.password = password;
}
public BlockInfo getBlockInfo(String blockHash) throws Exception {
JsonRpcRequest request = new JsonRpcRequest(
"2.0",
"getblock",
new Object[]{blockHash, 1},
System.currentTimeMillis()
);
String auth = Base64.getEncoder().encodeToString(
(username + ":" + password).getBytes()
);
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(java.net.URI.create(rpcUrl))
.header("Content-Type", "application/json")
.header("Authorization", "Basic " + auth)
.POST(HttpRequest.BodyPublishers.ofString(
objectMapper.writeValueAsString(request)
))
.build();
HttpResponse<String> response = httpClient.send(
httpRequest,
HttpResponse.BodyHandlers.ofString()
);
JsonNode result = objectMapper.readTree(response.body());
return objectMapper.convertValue(result.get("result"), BlockInfo.class);
}
}
class BlockInfo {
public String hash;
public long height;
public int confirmations;
public String time;
// ... остальные поля
}
Преимущества JSON-RPC
✅ Простота — текстовый формат, легко отлаживать ✅ Универсальность — работает с любым транспортом (HTTP, WebSocket, TCP) ✅ Асинхронность — легко реализовать async/await паттерны ✅ Язык-агностичность — работает с любым языком ✅ Батчинг — можно отправить несколько запросов одновременно
Недостатки
❌ Медленнее бинарных протоколов (gRPC, Protocol Buffers) ❌ Меньше стандартизации чем REST для HTTP ❌ Требует парсинга JSON — больше ресурсов чем бинарные форматы
Батчинг запросов
Частая практика в blockchain приложениях:
public List<String> getMultipleBalances(List<String> addresses) throws Exception {
List<JsonRpcRequest> requests = new ArrayList<>();
for (int i = 0; i < addresses.size(); i++) {
requests.add(new JsonRpcRequest(
"2.0",
"eth_getBalance",
new Object[]{addresses.get(i), "latest"},
i
));
}
String batchRequest = objectMapper.writeValueAsString(requests);
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(java.net.URI.create(ETHEREUM_RPC_URL))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(batchRequest))
.build();
HttpResponse<String> response = httpClient.send(
httpRequest,
HttpResponse.BodyHandlers.ofString()
);
List<JsonRpcResponse> responses = objectMapper.readValue(
response.body(),
objectMapper.getTypeFactory().constructCollectionType(List.class, JsonRpcResponse.class)
);
return responses.stream()
.map(r -> r.result)
.collect(Collectors.toList());
}
Когда использовать JSON-RPC
✅ Blockchain приложения (Ethereum, Bitcoin, Solana) ✅ Real-time коммуникация через WebSocket ✅ Интеграция с legacy системами ✅ Микросервисы нуждающиеся в простоте
❌ Высоконагруженные системы (используй gRPC) ❌ Публичные REST API (используй REST) ❌ Требуется максимальная производительность
Заключение
JSON-RPC — это проверенный и широко используемый протокол, особенно в blockchain экосистеме. Хотя REST API сейчас популярнее для веб-приложений, JSON-RPC остаётся актуальным выбором для специализированных задач, требующих простоты и универсальности.