improve & fix openrpc handler and http interface
This commit is contained in:
52
lib/schemas/openrpc/controller_http.v
Normal file
52
lib/schemas/openrpc/controller_http.v
Normal file
@@ -0,0 +1,52 @@
|
||||
module openrpc
|
||||
|
||||
import veb
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
// Main controller for handling RPC requests
|
||||
pub struct HTTPController {
|
||||
Handler // Handles JSON-RPC requests
|
||||
// pub mut:
|
||||
// handler Handler @[required]
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
veb.Context
|
||||
}
|
||||
|
||||
// Creates a new HTTPController instance
|
||||
pub fn new_http_controller(c HTTPController) &HTTPController {
|
||||
return &HTTPController{
|
||||
...c,
|
||||
Handler: c.Handler
|
||||
}
|
||||
}
|
||||
|
||||
// Parameters for running the server
|
||||
@[params]
|
||||
pub struct RunParams {
|
||||
pub:
|
||||
port int = 8080 // Default to port 8080
|
||||
}
|
||||
|
||||
// Starts the server
|
||||
pub fn (mut c HTTPController) run(params RunParams) {
|
||||
veb.run[HTTPController, Context](mut c, 8080)
|
||||
}
|
||||
|
||||
// Handles POST requests at the index endpoint
|
||||
@[post]
|
||||
pub fn (mut c HTTPController) index(mut ctx Context) veb.Result {
|
||||
// Decode JSONRPC Request from POST data
|
||||
request := jsonrpc.decode_request(ctx.req.data) or {
|
||||
return ctx.server_error('Failed to decode JSONRPC Request ${err.msg}')
|
||||
}
|
||||
|
||||
// Process the JSONRPC request with the OpenRPC handler
|
||||
response := c.handler.handle(request) or {
|
||||
return ctx.server_error('Handler error: ${err.msg}')
|
||||
}
|
||||
|
||||
// Encode and return the handler's JSONRPC Response
|
||||
return ctx.json(response)
|
||||
}
|
||||
@@ -20,7 +20,6 @@ fn handler(request jsonrpc.Request) !jsonrpc.Response {
|
||||
fn test_new_server() {
|
||||
specification := new(path: specification_path)!
|
||||
new_controller(
|
||||
specification: specification
|
||||
handler: Handler{
|
||||
specification: specification
|
||||
handler: handler
|
||||
@@ -31,7 +30,6 @@ fn test_new_server() {
|
||||
fn test_run_server() {
|
||||
specification := new(path: specification_path)!
|
||||
mut controller := new_controller(
|
||||
specification: specification
|
||||
handler: Handler{
|
||||
specification: specification
|
||||
handler: handler
|
||||
15
lib/schemas/openrpc/controller_ws.v
Normal file
15
lib/schemas/openrpc/controller_ws.v
Normal file
@@ -0,0 +1,15 @@
|
||||
module openrpc
|
||||
|
||||
import veb
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
// Main controller for handling RPC requests
|
||||
pub struct WebSocketController {
|
||||
pub mut:
|
||||
handler Handler @[required] // Handles JSON-RPC requests
|
||||
}
|
||||
|
||||
// Creates a new HTTPController instance
|
||||
pub fn new_websocket_controller(c WebSocketController) &WebSocketController {
|
||||
return &WebSocketController{...c}
|
||||
}
|
||||
50
lib/schemas/openrpc/handler.v
Normal file
50
lib/schemas/openrpc/handler.v
Normal file
@@ -0,0 +1,50 @@
|
||||
module openrpc
|
||||
|
||||
import x.json2
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
pub struct Handler {
|
||||
pub:
|
||||
specification OpenRPC @[required] // The OpenRPC specification
|
||||
pub mut:
|
||||
handler IHandler
|
||||
}
|
||||
|
||||
pub interface IHandler {
|
||||
mut:
|
||||
handle(jsonrpc.Request) !jsonrpc.Response // Custom handler for other methods
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct HandleParams {
|
||||
timeout int = 60 // Timeout in seconds
|
||||
retry int // Number of retries
|
||||
}
|
||||
|
||||
// Handle a JSON-RPC request and return a response
|
||||
pub fn (mut h Handler) handle(req jsonrpc.Request, params HandleParams) !jsonrpc.Response {
|
||||
// Validate the incoming request
|
||||
req.validate() or {
|
||||
return jsonrpc.new_error_response(req.id, jsonrpc.invalid_request)
|
||||
}
|
||||
|
||||
// Check if the method exists
|
||||
if req.method == 'rpc.discover' {
|
||||
// Handle the rpc.discover method
|
||||
spec_json := h.specification.encode()!
|
||||
return jsonrpc.new_response(req.id, spec_json)
|
||||
}
|
||||
|
||||
// Validate the method exists in the specification
|
||||
if req.method !in h.specification.methods.map(it.name) {
|
||||
return jsonrpc.new_error_response(req.id, jsonrpc.method_not_found)
|
||||
}
|
||||
|
||||
// Enforce timeout and retries (dummy implementation)
|
||||
if params.timeout < 0 || params.retry < 0 {
|
||||
return jsonrpc.new_error_response(req.id, jsonrpc.invalid_params)
|
||||
}
|
||||
|
||||
// Forward the request to the custom handler
|
||||
return h.handler.handle(req)
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
module openrpc
|
||||
|
||||
import veb
|
||||
import x.json2
|
||||
import freeflowuniverse.herolib.schemas.jsonrpc
|
||||
|
||||
// Main controller for handling RPC requests
|
||||
pub struct Controller {
|
||||
pub:
|
||||
specification OpenRPC @[required] // OpenRPC specification
|
||||
pub mut:
|
||||
handler Handler @[required] // Handles JSON-RPC requests
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
veb.Context
|
||||
}
|
||||
|
||||
// Creates a new Controller instance
|
||||
pub fn new_controller(c Controller) &Controller {
|
||||
return &Controller{...c}
|
||||
}
|
||||
|
||||
// Parameters for running the server
|
||||
@[params]
|
||||
pub struct RunParams {
|
||||
pub:
|
||||
port int = 8080 // Default to port 8080
|
||||
}
|
||||
|
||||
// Starts the server
|
||||
pub fn (mut c Controller) run(params RunParams) {
|
||||
veb.run[Controller, Context](mut c, 8080)
|
||||
}
|
||||
|
||||
// Handles POST requests at the index endpoint
|
||||
@[post]
|
||||
pub fn (mut c Controller) index(mut ctx Context) veb.Result {
|
||||
req_raw := json2.raw_decode(ctx.req.data) or {
|
||||
return ctx.server_error('Invalid JSON body') // Return error if JSON is malformed
|
||||
}
|
||||
|
||||
req_map := req_raw.as_map() // Converts JSON to a map
|
||||
|
||||
// Create a jsonrpc.Request using the decoded data
|
||||
request := jsonrpc.Request{
|
||||
jsonrpc: req_map['jsonrpc'].str()
|
||||
id: req_map['id'].str()
|
||||
method: req_map['method'].str()
|
||||
params: req_map['params'].str()
|
||||
}
|
||||
|
||||
// Process the request with the handler
|
||||
response := c.handler.handle(request) or {
|
||||
return ctx.server_error('Handler error: ${err.msg}')
|
||||
}
|
||||
|
||||
// Return the handler's response as JSON
|
||||
return ctx.json(response)
|
||||
}
|
||||
|
||||
pub struct Handler {
|
||||
specification OpenRPC
|
||||
pub mut:
|
||||
handler fn(jsonrpc.Request) !jsonrpc.Response
|
||||
}
|
||||
|
||||
// Handle a request and return a response
|
||||
pub fn (h Handler) handle(req jsonrpc.Request) !jsonrpc.Response {
|
||||
return h.handler(req)!
|
||||
}
|
||||
Reference in New Issue
Block a user