Хороший способ построить подчиненный роутер с помощью net / http - PullRequest
0 голосов
/ 25 марта 2020

Я создаю сервер API, который обрабатывает несколько путей с net / http . Я хотел бы построить его как подчиненный канал, но я не знаю, как это сделать.

Пока я думаю следующее.

package main

import (
    "database/sql"
    "log"
    "net/http"
)

type Config struct {
    db *sql.DB
}

type UserRouter struct {
    mux *http.ServeMux
    cfg *Config
}

func (u *UserRouter) Create(w http.ResponseWriter, r *http.Request) {
    // process handler logic
    w.Write([]byte("Create"))
}

func (u *UserRouter) Delete(w http.ResponseWriter, r *http.Request) {
    // process handler logic
    w.Write([]byte("Delete"))
}

// NewUserRouter is subrouter.
func NewUserRouter(cfg *Config) *UserRouter {
    mux := http.NewServeMux()
    u := &UserRouter{
        mux: mux,
        cfg: cfg,
    }
    mux.HandleFunc("/user/create", u.Create)
    mux.HandleFunc("/user/delete", u.Delete)
    return u
}

func (u *UserRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    u.mux.ServeHTTP(w, r)
}

func main() {
    mux := http.NewServeMux()
    cfg := &Config{nil /* Describes settings such as PostgreSQL. */}
    mux.Handle("/user/", NewUserRouter(cfg))
    if err := http.ListenAndServe(":8080", mux); err != nil {
        log.Fatal(err)
    }
}

Вышеприведенная реализация кажется немного избыточной. Но HTTP-сервер не будет работать должным образом, если путь подчиненного маршрутизатора задан следующим образом. Это связано с тем, что переданный в ListenAndServe мультиплексор отличается от мультиплексора подуровня, я думаю.

// NewUserRouter is subrouter.
func NewUserRouter(cfg *Config) *UserRouter {
    mux := http.NewServeMux()
    u := &UserRouter{
        mux: mux,
        cfg: cfg,
    }
-   mux.HandleFunc("/user/create", u.Create)
-   mux.HandleFunc("/user/delete", u.Delete)
+   mux.HandleFunc("/create", u.Create)
+   mux.HandleFunc("/delete", u.Delete)
    return u
}

Сложно ли создать простой подпрограмму с помощью net / http и нужно ли использовать WAF, например * 1011? *go -чи / чи или горилла / мукс ?

1 Ответ

1 голос
/ 25 марта 2020

Если ваша цель состоит в том, чтобы отделить регистрацию пользовательских обработчиков от других обработчиков, то сделайте что-то вроде следующего. Суб-маршрутизаторы не нужны.

type UserRouter struct {
    cfg *Config

    // prefix is the path prefix for the user handlers. Use this
    // value to construct paths to other user handlers.
    prefix string 
}

// RegisterUserHandler adds the user handlers to mux using the
// specified path prefix.
func RegisterUserHandler(cfg *Config, prefix string, mux *http.ServeMux)  {
    u := &UserRouter{cfg: cfg, prefix: prefix}
    mux.HandleFunc(prefix+"/create", u.Create)
    mux.HandleFunc(prefix+"/delete", u.Delete)
}

func main() {
    mux := http.NewServeMux()
    cfg := &Config{nil /* Describes settings such as PostgreSQL. */}
    RegisterUserHandler(cfg, "/user", mux)
    log.Fatal(http.ListenAndServe(":8080", mux))
}
...