6.4 KiB
6.4 KiB
OpenRPC Manager Implementation Plan
1. Understanding the Requirements
The task requires us to:
- Create an OpenRPC Manager (ORPCManager)
- Read JSON files from services in pkg/openrpc
- Create a model for OpenRPC spec in a separate file
- Read the OpenRPC specs into the model
- Keep these models in memory in the ORPCManager
- Create supporting methods like list_methods
- Create a command in @cmd/ to test this behavior
2. Project Structure
Here's the proposed file structure for our implementation:
pkg/
openrpc/
models/
spec.go # OpenRPC specification model
manager.go # ORPCManager implementation
cmd/
orpctest/
main.go # Test command for the ORPCManager
3. Implementation Details
3.1 OpenRPC Specification Model (pkg/openrpc/models/spec.go)
We'll create a Go struct model that represents the OpenRPC specification based on the structure observed in zinit.json:
classDiagram
class OpenRPCSpec {
+string OpenRPC
+InfoObject Info
+Server[] Servers
+Method[] Methods
}
class InfoObject {
+string Version
+string Title
+string Description
+LicenseObject License
}
class LicenseObject {
+string Name
}
class Server {
+string Name
+string URL
}
class Method {
+string Name
+string Description
+Parameter[] Params
+ResultObject Result
+Example[] Examples
+ErrorObject[] Errors
}
class Parameter {
+string Name
+string Description
+bool Required
+SchemaObject Schema
}
class ResultObject {
+string Name
+string Description
+SchemaObject Schema
}
class SchemaObject {
+string Type
+map[string]interface{} Properties
+SchemaObject Items
+map[string]SchemaObject AdditionalProperties
}
class Example {
+string Name
+map[string]interface{}[] Params
+ExampleResultObject Result
}
class ExampleResultObject {
+string Name
+interface{} Value
}
class ErrorObject {
+int Code
+string Message
+string Data
}
OpenRPCSpec --> InfoObject
OpenRPCSpec --> Server
OpenRPCSpec --> Method
Method --> Parameter
Method --> ResultObject
Method --> Example
Method --> ErrorObject
Parameter --> SchemaObject
ResultObject --> SchemaObject
Example --> ExampleResultObject
3.2 OpenRPC Manager (pkg/openrpc/manager.go)
The ORPCManager will be responsible for:
- Loading OpenRPC specifications from JSON files
- Storing and managing these specifications in memory
- Providing methods to access and manipulate the specifications
classDiagram
class ORPCManager {
-map[string]*OpenRPCSpec specs
+NewORPCManager() *ORPCManager
+LoadSpecs(dir string) error
+LoadSpec(path string) error
+GetSpec(name string) *OpenRPCSpec
+ListSpecs() []string
+ListMethods(specName string) []string
+GetMethod(specName string, methodName string) *Method
}
ORPCManager --> OpenRPCSpec
3.3 Test Command (cmd/orpctest/main.go)
We'll create a command-line tool to test the ORPCManager functionality:
- Initialize the ORPCManager
- Load specifications from the pkg/openrpc/services directory
- List available specifications
- List methods for each specification
- Display details for specific methods
4. Implementation Steps
-
Create the OpenRPC Specification Model:
- Define the Go structs for the OpenRPC specification
- Implement JSON marshaling/unmarshaling
- Add validation functions
-
Implement the ORPCManager:
- Create the manager struct with a map to store specifications
- Implement methods to load specifications from files
- Implement methods to access and manipulate specifications
-
Create the Test Command:
- Implement a command-line interface to test the ORPCManager
- Add options to list specifications, methods, and display details
-
Write Tests:
- Write unit tests for the OpenRPC model
- Write unit tests for the ORPCManager
- Write integration tests for the entire system
5. Detailed Method Specifications
5.1 ORPCManager Methods
NewORPCManager()
- Creates a new instance of the ORPCManager
- Initializes the specs map
LoadSpecs(dir string) error
- Reads all JSON files in the specified directory
- For each file, calls LoadSpec()
- Returns an error if any file fails to load
LoadSpec(path string) error
- Reads the JSON file at the specified path
- Parses the JSON into an OpenRPCSpec struct
- Validates the specification
- Stores the specification in the specs map using the filename (without extension) as the key
- Returns an error if any step fails
GetSpec(name string) *OpenRPCSpec
- Returns the OpenRPCSpec with the specified name
- Returns nil if the specification doesn't exist
ListSpecs() []string
- Returns a list of all loaded specification names
ListMethods(specName string) []string
- Returns a list of all method names in the specified specification
- Returns an empty list if the specification doesn't exist
GetMethod(specName string, methodName string) *Method
- Returns the Method with the specified name from the specified specification
- Returns nil if the specification or method doesn't exist
6. Example Usage
// Initialize the ORPCManager
manager := openrpc.NewORPCManager()
// Load all specifications from the services directory
err := manager.LoadSpecs("pkg/openrpc/services")
if err != nil {
log.Fatalf("Failed to load specifications: %v", err)
}
// List all loaded specifications
specs := manager.ListSpecs()
fmt.Println("Loaded specifications:")
for _, spec := range specs {
fmt.Printf("- %s\n", spec)
}
// List all methods in the zinit specification
methods := manager.ListMethods("zinit")
fmt.Println("\nMethods in zinit specification:")
for _, method := range methods {
fmt.Printf("- %s\n", method)
}
// Get details for a specific method
method := manager.GetMethod("zinit", "service_list")
if method != nil {
fmt.Printf("\nDetails for method 'service_list':\n")
fmt.Printf("Description: %s\n", method.Description)
fmt.Printf("Parameters: %d\n", len(method.Params))
fmt.Printf("Examples: %d\n", len(method.Examples))
}