Co-authored-by: marbar3778 <marbar3778@yahoo.com> Co-authored-by: Marko <marko@baricevic.me>
99 lines
4.7 KiB
Go
99 lines
4.7 KiB
Go
package schema
|
|
|
|
// APIDescriptor is a public versioned descriptor of an API.
|
|
//
|
|
// An APIDescriptor can be used as a native descriptor of an API's encoding.
|
|
// The native binary encoding of API requests and responses is to encode the input and output
|
|
// fields using value binary encoding.
|
|
// The native JSON encoding would be to encode the fields as a JSON object, canonically
|
|
// sorted by field name with no extra whitespace.
|
|
// Thus, APIDefinitions have deterministic binary and JSON encodings.
|
|
//
|
|
// APIDefinitions have a strong definition of compatibility between different versions
|
|
// of the same API.
|
|
// It is an INCOMPATIBLE change to add new input fields to existing methods or to remove or modify
|
|
// existing input or output fields.
|
|
// Input fields also cannot reference any unsealed structs, directly or transitively,
|
|
// because these types allow adding new fields.
|
|
// Adding new input fields to a method introduces the possibility that a newer client
|
|
// will send an incomprehensible message to an older server.
|
|
// The only safe ways that input field schemas can be extended are by adding
|
|
// new values to EnumType's and new cases to OneOfType's.
|
|
// It is a COMPATIBLE change to add new methods to an API and to add new output fields
|
|
// to existing methods.
|
|
// Output fields can reference any sealed or unsealed StructType, directly or transitively.
|
|
//
|
|
// Existing protobuf APIs could also be mapped into APIDefinitions, and used in the following ways:
|
|
// - to produce, user-friendly deterministic JSON
|
|
// - to produce a deterministic binary encoding
|
|
// - to check for compatibility in a way that is more appropriate to blockchain applications
|
|
// - to use any code generators designed to support this spec as an alternative to protobuf
|
|
// Also, a standardized way of serializing schema types as protobuf could be defined which
|
|
// maps to the original protobuf encoding, so that schemas can be used as an interop
|
|
// layer between different less expressive encoding systems.
|
|
//
|
|
// Existing EVM contract APIs expressed in Solidity could be mapped into APIDefinitions, and
|
|
// a mapping of all schema values to ABI encoding could be defined which preserves the
|
|
// original ABI encoding.
|
|
//
|
|
// In this way, we can define an interop layer between contracts in the EVM world,
|
|
// SDK modules accepting protobuf types, and any API using this schema system natively.
|
|
type APIDescriptor struct {
|
|
// Name is the versioned name of the API.
|
|
Name string
|
|
|
|
// Methods is the list of methods in the API.
|
|
// It is a COMPATIBLE change to add new methods to an API.
|
|
// If a newer client tries to call a method that an older server does not recognize it,
|
|
// an error will simply be returned.
|
|
Methods []MethodDescriptor
|
|
}
|
|
|
|
// MethodDescriptor describes a method in the API.
|
|
type MethodDescriptor struct {
|
|
// Name is the name of the method.
|
|
Name string
|
|
|
|
// InputFields is the list of input fields for the method.
|
|
//
|
|
// It is an INCOMPATIBLE change to add, remove or update input fields to a method.
|
|
// The addition of new fields introduces the possibility that a newer client
|
|
// will send an incomprehensible message to an older server.
|
|
// InputFields can only reference sealed StructTypes, either directly and transitively.
|
|
//
|
|
// As a special case to represent protobuf service definitions, there can be a single
|
|
// unnamed struct input field that code generators can choose to either reference
|
|
// as a named struct or to expand inline as function arguments.
|
|
InputFields []Field
|
|
|
|
// OutputFields is the list of output fields for the method.
|
|
//
|
|
// It is a COMPATIBLE change to add new output fields to a method,
|
|
// but existing output fields should not be removed or modified.
|
|
// OutputFields can reference any sealed or unsealed StructType, directly or transitively.
|
|
// If a newer client tries to call a method on an older server, the newer expected result output
|
|
// fields will simply be populated with the default values for that field kind.
|
|
//
|
|
// As a special case to represent protobuf service definitions, there can be a single
|
|
// unnamed struct output field.
|
|
// In this case, adding new output fields is an INCOMPATIBLE change (because protobuf service definitions
|
|
// don't allow this), but new fields can be added to the referenced struct if it is unsealed.
|
|
OutputFields []Field
|
|
|
|
// Volatility is the volatility of the method.
|
|
Volatility Volatility
|
|
}
|
|
|
|
// Volatility is the volatility of a method.
|
|
type Volatility int
|
|
|
|
const (
|
|
// PureVolatility indicates that the method can neither read nor write state.
|
|
PureVolatility Volatility = iota
|
|
// ReadonlyVolatility indicates that the method can read state but not write state.
|
|
ReadonlyVolatility
|
|
|
|
// VolatileVolatility indicates that the method can read and write state.
|
|
VolatileVolatility
|
|
)
|