xrpc

package module
v0.0.0-...-d09c437 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2025 License: MIT Imports: 13 Imported by: 0

README

xRPC

This project was inspired by TRPC and Zod. It provides a simple and flexible way to define and validate input for HTTP procedures using Echo as the HTTP server.

Features

  • Validation: Define validation rules for your input types.
  • Procedures: Create query and mutation procedures with type-safe input and output.
  • Echo Integration: Easily integrate with Echo to handle HTTP requests and responses.

Installation

To install the library, run:

go get github.com/struckchure/xrpc

Usage

Define Your Types

Define the types for your input and output:

type Post struct {
  Id      int    `json:"id"`
  Title   string `json:"title"`
  Content string `json:"content"`
}

type ListPostInput struct {
  Skip  *int `query:"skip" json:"skip"`
  Limit *int `query:"limit" json:"limit"`
}

type CreatePostInput struct {
  Title   string `json:"title"`
  Content string `json:"content"`
}

type GetPostInput struct {
  Id       *int   `query:"id" json:"id"`
  AuthorId string `query:"author_id" json:"author_id"`
}
Create Procedures

Create procedures for listing posts, creating a post, and getting a post:

func main() {
  t := xrpc.InitTRPC()

  listPostsProcedure := xrpc.NewProcedure[ListPostInput, []Post]("list").
    Input(xrpc.NewValidator().
      Field("Skip", xrpc.Number().Min(0).Required()).
      Field("Limit", xrpc.Number().Max(10)),
    ).
    Query(func(c xrpc.Context[ListPostInput, []Post]) error {
      return c.Json(200, []Post{})
    })

  createPostProcedure := xrpc.NewProcedure[CreatePostInput, *Post]("create").
    Input(xrpc.NewValidator().
      Field("Title", xrpc.String().MinLength(10)).
      Field("Content", xrpc.String().MinLength(10)),
    ).
    Mutation(func(c xrpc.Context[CreatePostInput, *Post]) error {
      return c.Json(201, &Post{})
    })

  getPostProcedure := xrpc.NewProcedure[GetPostInput, *Post]("get").
    Input(xrpc.NewValidator().
      Field("Id", xrpc.Number().Required()).
      Field("AuthorId", xrpc.String()),
    ).
    Query(func(c xrpc.Context[GetPostInput, *Post]) error {
      return c.Json(200, &Post{})
    })

  listPostsProcedure(t)
  createPostProcedure(t)
  getPostProcedure(t)

  t.Start(9090)
}
Running the HTTP Server

The main function initializes the TRPC instance, defines the procedures, and starts the Echo HTTP server on port 9090.

Custom Validation Library

The custom validation library provides a fluent API for defining validation rules. The library supports validation for various types such as strings and numbers, and allows specifying custom error messages.

Example Usage
validator := xrpc.NewValidator().
  Field("Name", xrpc.String().MinLength(3).MaxLength(50)).
  Field("Email", xrpc.String().Email()).
  Field("Age", xrpc.Number().Min(18).Max(65))

err := validator.Validate(input)
if err != nil {
  // handle validation error
}

License

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgements

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func JoinPath

func JoinPath(paths ...string) string

func StripSlash

func StripSlash(path string) string

func WriteFile

func WriteFile(filename string, content string) error

WriteFile creates a new file and writes content to it. It returns an error if the file cannot be created or written to.

Types

type App

type App struct {
	// contains filtered or unexported fields
}

func (*App) Ctx

func (a *App) Ctx(modifiers ...func(Context[any, any]) Context[any, any]) Context[any, any]

func (*App) GenerateSpec

func (a *App) GenerateSpec()

func (*App) Get

func (a *App) Get(route Route) string

func (*App) Injector

func (a *App) Injector() *do.Injector

func (*App) Post

func (a *App) Post(route Route) string

func (*App) Router

func (a *App) Router(path string, procedures ...func(string, IApp)) IApp

func (*App) Server

func (a *App) Server() *echo.Echo

func (*App) Spec

func (a *App) Spec(modifier func(TRPCSpec) TRPCSpec)

func (*App) Start

func (a *App) Start(port int) error

func (*App) Use

func (a *App) Use(middlewares ...ProcedureCallback[any, any]) IApp

type Context

type Context[T, R any] struct {
	Injector *do.Injector
	Input    T
	// contains filtered or unexported fields
}

func (*Context[T, R]) Header

func (c *Context[T, R]) Header(key string) string

func (*Context[T, R]) Json

func (c *Context[T, R]) Json(status int, body R) error

func (*Context[T, R]) Locals

func (c *Context[T, R]) Locals(key string, value ...interface{}) interface{}

func (*Context[T, R]) Redirect

func (c *Context[T, R]) Redirect(status int, url string) error

func (*Context[T, R]) String

func (c *Context[T, R]) String(status int, body string) error

type FieldDescriptor

type FieldDescriptor struct {
	Name     string `yaml:"name"`
	Alias    string `yaml:"alias"`
	Type     string `yaml:"type"`
	Nillable bool   `yaml:"nillable"`
}

type IApp

type IApp interface {
	Injector() *do.Injector
	Spec(modifier func(TRPCSpec) TRPCSpec)
	GenerateSpec()
	Server() *echo.Echo
	Ctx(...func(Context[any, any]) Context[any, any]) Context[any, any]
	Use(...ProcedureCallback[any, any]) IApp
	Router(string, ...func(string, IApp)) IApp
	Get(Route) string
	Post(Route) string
	Start(port int) error
}

func NewXRPC

func NewXRPC(cfg ...XRPCConfig) IApp

type IProcedure

type IProcedure[T, R any] interface {
	Input(*validation.Validator) IProcedure[T, R]
	Use(...ProcedureCallback[T, R]) IProcedure[T, R]
	Query(ProcedureCallback[T, R]) func(string, IApp)
	Mutation(ProcedureCallback[T, R]) func(string, IApp)
}

func NewProcedure

func NewProcedure[T, R any](name string) IProcedure[T, R]

type Procedure

type Procedure[T, R any] struct {
	// contains filtered or unexported fields
}

func (*Procedure[T, R]) Input

func (p *Procedure[T, R]) Input(v *validation.Validator) IProcedure[T, R]

func (*Procedure[T, R]) Mutation

func (p *Procedure[T, R]) Mutation(callback ProcedureCallback[T, R]) func(string, IApp)

func (*Procedure[T, R]) Query

func (p *Procedure[T, R]) Query(callback ProcedureCallback[T, R]) func(string, IApp)

func (*Procedure[T, R]) Use

func (p *Procedure[T, R]) Use(middlewares ...ProcedureCallback[T, R]) IProcedure[T, R]

type ProcedureCallback

type ProcedureCallback[T, R any] func(Context[T, R]) error

type Route

type Route struct {
	// contains filtered or unexported fields
}

type TRPCSpec

type TRPCSpec struct {
	Name       string              `yaml:"name"`
	ServerUrl  string              `yaml:"server_url"`
	Procedures []XRPCSpecProcedure `yaml:"procedures"`
}

type TypeDescriptor

type TypeDescriptor struct {
	TypeName string            `yaml:"type_name,omitempty"`
	Fields   []FieldDescriptor `yaml:"fields,omitempty"`
	Nillable bool              `yaml:"nillable"`
	Array    *TypeDescriptor   `yaml:"array,omitempty"`
}

type XRPCConfig

type XRPCConfig struct {
	Name            string
	ServerUrl       string
	AutoGenTRPCSpec bool
	SpecPath        string
}

type XRPCError

type XRPCError struct {
	Code   int `json:"-"`
	Detail any `json:"detail"`
}

func (*XRPCError) Error

func (e *XRPCError) Error() string

type XRPCSpecProcedure

type XRPCSpecProcedure struct {
	Path   string                `yaml:"path"`
	Type   XRPCSpecProcedureType `yaml:"type"`
	Input  TypeDescriptor        `yaml:"input"`
	Output TypeDescriptor        `yaml:"output"`
}

type XRPCSpecProcedureType

type XRPCSpecProcedureType string
const (
	XRPCSpecProcedureTypeQuery    XRPCSpecProcedureType = "Query"
	XRPCSpecProcedureTypeMutation XRPCSpecProcedureType = "Mutation"
)

Directories

Path Synopsis
example
basic-server command
go-client command
ts-client command
validation command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL