package rest import ( "log" "sync" "sync/atomic" "time" ) type ExampleGroup struct { *Fielder ID int64 Name string } type ExampleUser struct { *Fielder ID int64 Name string Token string Group *ExampleGroup } // ExapmleApp реализует интерфейс IApplication, который отдает серверу параметры подключения, // секретный ключ шифрования токена авторизации, // а так же обрабатывает поступающие запросы type ExampleApp struct { SAddr string SSecret []byte Users *sync.Map Groups *sync.Map IDCounter int64 } func (s *ExampleApp) GenerateID() int64 { id := atomic.AddInt64(&s.IDCounter, 1) return id } func (s *ExampleApp) Addr() string { return s.SAddr } func (s *ExampleApp) Secret() []byte { return s.SSecret } func (s *ExampleApp) Executer(r *Request) (IExecuter, bool) { return nil, false } var ExampleEngine *ExampleApp // ExampleNew показывает пример создания и запуска сервера с RestAPI func ExampleNew() { // создаем новый сервер с использованием приложения ExampleApp ExampleEngine = &ExampleApp{ SAddr: "localhost:8080", SSecret: []byte("top-secret"), Users: new(sync.Map), Groups: new(sync.Map), IDCounter: 1, } // Добавляем публичную группу groupID := ExampleEngine.GenerateID() ExampleEngine.Groups.Store( groupID, &ExampleGroup{ ID: groupID, Name: "public", }, ) // создаем сервер restServ := New(ExampleEngine) // пробуем запустить его. Если через секунду запуск не удался, будет возвращена ошибка if err := restServ.Listen(time.Second); err != nil { // ошибка запуска log.Fatal(err) } } //////////////////////////////////////////////////////////// type ExampleRequestRegister struct { ID int64 Name string `rest:"required"` RoleIDS []int64 `rest:"required"` GroupID int64 `rest:"required"` // Объект группы, который определяется в валидации. // В боевых условиях это поле должно быть приватное. Group *ExampleGroup } func (s *ExampleRequestRegister) Validate(req *Request) *Response { // пользователь не должен быть авторизован if req.auth != nil { return ResponseErrorMessage("AlreadyAuthorized", "User is already authorized", 500) } // проверяем имя //if s.Name = strings.TrimSpace() // вилидируем группу group, check := ExampleEngine.Groups.Load(s.GroupID) if !check { return ResponseErrorMessage("GroupNotFound", "Group is not found", 500) } // Устанавливаем группу для использования в методе выполняния, // чтобы не выбирать её снова s.Group = group.(*ExampleGroup) return nil } func (s *ExampleRequestRegister) Execute(req *Request) *Response { userID := ExampleEngine.GenerateID() user := &ExampleUser{ ID: userID, Name: s.Name, Group: s.Group, } user.Fielder = NewFielder(user) ExampleEngine.Users.Store(userID, user) fields, err := user.Fielder.Fields(req.Data().Slice("fields", nil)...) if err != nil { return ResponseErrorMessage("FieldsError", err.Error(), 500) } return ResponseSuccess(fields, nil) }