qiwlar

package module
v0.9.1 Latest Latest
Warning

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

Go to latest
Published: Nov 17, 2023 License: MIT Imports: 7 Imported by: 0

README

Qiwlar

Этот фреймворк вдохновлен NestJS и предназначен для создания легко масштабируемых серверных приложений. Он использует стандартный пакет net/http для обработки запросов и julienschmidt/httprouter для маршрутизации.

Установка

go get github.com/levnikort/qiwlar

Модули

Модуль — это структура, содержащая хотя бы одно из четырех полей:

  1. Imports — список импортированных модулей, которые экспортируют необходимые провайдеры или другие модули.
  2. Providers — поле, необходимое для регистрации провайдеров, чтобы в дальнейшем передавать их другим элементам, которые этого требуют.
  3. Controllers — набор контроллеров, определенных в этом модуле, экземпляры которых необходимо создать.
  4. Exports — список провайдеров или модулей, которые будут доступны в других модулях.
type AppModule struct {
  Imports     func(foo.FooModule{})
  Providers   func(AppProvider)
  Controllers func(AppController)
  Exports     func(AppProvider, foo.FooModule{})
}

или

type AppModule struct {
  Controllers func(AppController)
}

У модуля можно реализовать метод UseRegister, необходимый для регистрации изолированного модуля. Проще говоря, создается абсолютно новая копия модуля, в которую также можно передать тип qiwlar.Provide. Этот тип используется для передачи каких-либо настроек, например, адреса для подключения к базе данных. qiwlar.Provide передается в поле Provider создаваемого модуля.

Примечание: Доступ к qiwlar.Provide можно получить из метода Bind() в провайдере или контроллере.

type AppModule struct {
  Controllers func(AppController)
}

func (am AppModule) UseRegister() qiwlar.Provides {
  return qiwlar.Provides{
    reflect.TypeOf(foo.FooModule{}): {
      Name: "FOO"
      Value: map[string]interface{}{"opt": false} 
    }
  }
}

В приложении обязательно должен быть корневой модуль, с которого начинается построение графа и в дальнейшем внедрение зависимостей.

// Точка входа

func main() {
  q := qiwlar.New(app.AppModule{}).Run(":8080")
}

Провайдеры

Провайдер — это структура, которая должна содержать метод Bind(). Основная идея провайдера заключается в том, что он может быть внедрен как зависимость.

Метод Bind() в провайдере и контроллере необходим для распределения зависимостей внутри структуры, а также его можно использовать как функцию инициализации. То есть при создании провайдера или контроллера можно выполнить какой-либо дополнительный код.

type AppProvider struct {}
func (ap *AppProvider) Bind() {}
type AppProvider struct {
  fp *foo.FooProvider
}

func (ap *AppProvider) Bind(fp *foo.FooProvider) {
  ap.fp = fp
}
type AppProvider struct {
  fp *foo.FooProvider
}

func (ap *AppProvider) Bind(fp *foo.FooProvider) {
  ap.fp = fp

  // Выполнение дополнительного кода.
  db.DBConnect("Data")
}

Контроллеры

Контроллер — это структура, которая должна включать в себя qiwlar.Controller и содержать методы Bind(), Build().

Цель контроллера — обрабатывать определенные запросы для приложения. Механизм маршрутизации управляет тем, какой из контроллеров обрабатывает какие запросы. Зачастую каждый контроллер имеет более одного маршрута, и разные маршруты могут выполнять разные действия.

Метод Build() необходим для начала сборки контроллера.

Метод Collect() собирает конечные точки из декораторов и функций.

Метод Prefix() добавляет префикс ко всем путям в контроллере.

Метод ForAll() применяет декораторы ко всем конечным точкам в контроллере.

type AppController struct {
  qiwlar.Controller
  as *AppService
}

func (ac *AppController) Bind(as *AppService) {
  ac.as = as
}

func (ac *AppController) Build() {
  ac.Collect([]interface{}{
    ac.Prefix("v1"),
    ac.ForAll(d.MyLogger())

    d.Post("test/:id")
    d.Validate(UserDTO{})
    d.Params()
    func(dto UserDTO, params httprouter.Params) string {
      return params.ByName("id")
    }

    d.Get("cats")
    func() any {
      return "no"
    }

    // Вернуть ошибку, с http кодом 500
    d.Get("error")
    func() any {
      return qiwlar.Exception{StatusCode: 500, Data: "server error"}
    }
  })
}

Декораторы

Декоратор — это функция, которая реализует тип qiwlar.Decorator. Декоратор представляет собой, по сути, промежуточное программное обеспечение.

Пример простой реализации декоратора выглядит следующим образом:

func MyLoggerMethod() qiwlar.Decorator {
  return func(q *qiwlar.QResponse) interface{} {
    fmt.Println(q.Method)
    
    return nil
  }
}

Если мы хотим, чтобы наш декоратор предоставлял какие-то данные конечной функции:

type CurrentMethod string

func MyLoggerMethod() qiwlar.Decorator {
  return func(q *qiwlar.QResponse) interface{} {
    fmt.Println(q.Method)

    q.Results = append(Results, CurrentMethod(q.Method))

    return nil
  }
}

Если в декораторе может произойти ошибка, то мы можем обработать ее следующим образом: если декоратор предоставляет какие-либо данные, то до выхода из функции и возврата ошибки, он должен передать в q.Results пустой тип данных.

type CurrentMethod string

func MyLoggerMethod() qiwlar.Decorator {
  return func(q *qiwlar.QResponse) interface{} {
    fmt.Println(q.Method)

    err := logic(...)

    if err != nil {
      q.StatusCode = 400
      q.Results = append(q.Results, CurrentMethod(""))
      return err
    }

    q.Results = append(Results, CurrentMethod(q.Method))

    return nil
  }
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AnswerScheme

type AnswerScheme struct {
	StatusCode int         `json:"status_code"`
	Errors     interface{} `json:"errors"`
	Data       interface{} `json:"data"`
}

type Controller

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

func (*Controller) Collect

func (c *Controller) Collect(parts []interface{})

func (*Controller) EndPoints

func (c *Controller) EndPoints() []EndPoint

func (*Controller) ForAll

func (c *Controller) ForAll(decorators ...Decorator) struct{}

func (*Controller) Prefix

func (c *Controller) Prefix(prefix string) struct{}

type Decorator

type Decorator func(*QResponse) interface{}

type EndPoint

type EndPoint struct {
	Decorators []Decorator
	Fn         interface{}
}

type Exception

type Exception struct {
	StatusCode int
	Data       interface{}
}

func (*Exception) Error

func (e *Exception) Error() string

type Provide

type Provide struct {
	Name  string
	Value interface{}
}

type Provides

type Provides map[reflect.Type]Provide

type QResponse

type QResponse struct {
	Start        bool
	StatusCode   int
	Method       string
	Path         string
	CustomFormat func(AnswerScheme) interface{}
	Results      []interface{}
	W            http.ResponseWriter
	R            *http.Request
}

type Qiwlar

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

func New

func New(metaModule interface{}) *Qiwlar

func (*Qiwlar) Run

func (q *Qiwlar) Run(port string)

func (*Qiwlar) SetPanicHandler

func (q *Qiwlar) SetPanicHandler(ph func(qr *QResponse, r interface{}))

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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