===== JSON-RPC ===== A JSON-RPC (JavaScript Object Notation – Remote Procedure Call) egy egyszerű és könnyű súlyú távoli eljáráshívási (RPC) protokoll, amely az üzenetek formátumaként a JSON adatformátumot használja. A protokoll célja, hogy egy kliens egy távoli szerveren található függvényeket vagy metódusokat úgy tudjon meghívni, mintha azok helyben futó függvények lennének. A REST-alapú webszolgáltatásokkal szemben, amelyek erőforrás-orientált szemléletet követnek, a JSON-RPC eljárás-orientált megközelítést alkalmaz. Ez azt jelenti, hogy a kliens közvetlenül egy megnevezett metódust hív meg, és átadja a szükséges paramétereket. A JSON-RPC legfontosabb tulajdonságai a következők: * **Transport-független** – A protokoll csak az üzenetek formátumát határozza meg, a kommunikációs csatornát nem. A JSON-RPC használható például HTTP, HTTPS, WebSocket vagy TCP felett, de akár üzenetsorok vagy beágyazott rendszerek soros kommunikációja felett is. Emiatt könnyen integrálható különböző rendszerarchitektúrákba. * **Állapotmentes (stateless)** – Minden kérés tartalmaz minden szükséges információt a feldolgozáshoz: a metódus nevét, a paramétereket és a kérés azonosítóját. A szervernek nem kell állapotot vagy munkamenetadatokat tárolnia a hívások között. Ez egyszerűbbé teszi a skálázást és a terheléselosztást elosztott rendszerekben. * **Könnyű súlyú (lightweight)** – Az üzenetstruktúra nagyon egyszerű, csak néhány kötelező mezőt tartalmaz. Nincsenek bonyolult erőforrás-leírások vagy URL-hierarchiák, ezért az üzenetek mérete kicsi, és a feldolgozás gyors. * **Egyszerű implementáció** – A JSON feldolgozása szinte minden programozási nyelven támogatott. Egy JSON-RPC szerver implementálásához általában elegendő egy JSON-feldolgozó könyvtár, egy mechanizmus a metódusnevek függvényekhez rendelésére, valamint egy alapvető hibakezelés. * **Nyelvfüggetlen** – Mivel a JSON egy általánosan használt adatcsere-formátum, a kliens és a szerver különböző programozási nyelveken is megvalósíthatók. Például egy Python kliens kommunikálhat egy Java vagy C++ szerverrel, ha mindkét fél követi a JSON-RPC 2.0 specifikációt. A jelenleg legelterjedtebb verzió a **JSON-RPC 2.0**. https://www.jsonrpc.org/specification ==== JSON-RPC 2.0 üzenetstruktúra ==== Egy JSON-RPC kérés egy JSON objektum, amely a következő mezőket tartalmazza: * **jsonrpc** – a protokoll verziója (kötelezően "2.0") * **method** – a meghívandó távoli metódus neve * **params** – a metódus paraméterei (nem kötelező) * **id** – a kérés azonosítója (a válasz párosításához) Példa kérés: { "jsonrpc": "2.0", "method": "add", "params": [5, 7], "id": 1 } Sikeres válasz esetén a szerver a következő formátumú üzenetet küldi: { "jsonrpc": "2.0", "result": 12, "id": 1 } Ha hiba történik, a válasz egy **error** objektumot tartalmaz: { "jsonrpc": "2.0", "error": { "code": -32601, "message": "Method not found" }, "id": 1 } ==== Notifications (értesítések) ==== Ha a kliens **id mező nélkül** küld egy kérést, azt a JSON-RPC **notification** üzenetnek tekinti. Ebben az esetben a szerver **nem küld vissza választ**, mivel a kliens nem vár eredményt. Példa: { "jsonrpc": "2.0", "method": "logEvent", "params": {"event": "started"} } ==== Batch kérések ==== A JSON-RPC lehetővé teszi, hogy a kliens egyszerre több kérést küldjön egyetlen üzenetben. Ilyenkor a kérések egy JSON-tömbben szerepelnek. [ {"jsonrpc": "2.0", "method": "add", "params": [1,2], "id": 1}, {"jsonrpc": "2.0", "method": "subtract", "params": [5,3], "id": 2} ] ==== REST vs JSON-RPC ==== ^ Jellemző ^ REST ^ JSON-RPC ^ | Architektúra | Erőforrás-alapú | Eljárás-alapú | | Végpontok | Több endpoint | Általában egy endpoint | | HTTP metódusok használata | Igen | Nem szükséges | | Szabvány típusa | Architektúrális elvek | Protokoll specifikáció | | Tipikus használat | Publikus web API-k | Belső API-k, blockchain | A REST API-kat gyakran használják nyilvános webes szolgáltatásoknál, míg a JSON-RPC gyakrabban jelenik meg belső rendszerekben vagy blokklánc-interfészekben. ==== Gyakorlati példa Python nyelven ==== Ebben a példában egy egyszerű JSON-RPC szervert és klienst valósítunk meg Python nyelven. A következő könyvtárakat használjuk: * **Flask** – HTTP szerver létrehozásához * **requests** – HTTP kliens megvalósításához A szükséges csomagok telepítése: pip install flask requests ===== JSON-RPC szerver (Python + Flask) ===== Hozzunk létre egy //server.py// nevű fájlt. from flask import Flask, request, jsonify app = Flask(__name__) # elérhető RPC metódusok def add(a, b): return a + b def subtract(a, b): return a - b methods = { "add": add, "subtract": subtract, } @app.route("/rpc", methods=["POST"]) def rpc(): data = request.get_json() if data.get("jsonrpc") != "2.0": return jsonify( { "jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": data.get("id"), } ) method_name = data.get("method") params = data.get("params", []) request_id = data.get("id") if method_name not in methods: return jsonify( { "jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": request_id, } ) try: result = methods[method_name](*params) return jsonify( { "jsonrpc": "2.0", "result": result, "id": request_id, } ) except Exception as e: return jsonify( { "jsonrpc": "2.0", "error": {"code": -32603, "message": str(e)}, "id": request_id, } ) if __name__ == "__main__": app.run(port=5000) A szerver indítása: python server.py ===== JSON-RPC kliens (Python) ===== Hozzunk létre egy //client.py// nevű fájlt. import requests import json url = "http://localhost:5000/rpc" payload = { "jsonrpc": "2.0", "method": "add", "params": [10, 15], "id": 1 } response = requests.post(url, json=payload) print("Status:", response.status_code) print("Response:", response.json()) Várható kimenet: Status: 200 Response: {'jsonrpc': '2.0', 'result': 25, 'id': 1} ==== JSON-RPC 2.0 hibakódok ==== ^ Code ^ Jelentés ^ | -32700 | Parse error – JSON feldolgozási hiba | | -32600 | Invalid Request – hibás kérésformátum | | -32601 | Method not found – a metódus nem létezik | | -32602 | Invalid params – hibás paraméterek | | -32603 | Internal error – szerver oldali hiba |