github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/web/routes.go (about)

     1  package web
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  	"net/http/pprof"
     7  
     8  	"github.com/ShoshinNikita/budget-manager/internal/pkg/reqid"
     9  	"github.com/ShoshinNikita/budget-manager/internal/web/api"
    10  	"github.com/ShoshinNikita/budget-manager/internal/web/pages"
    11  	"github.com/ShoshinNikita/budget-manager/internal/web/utils"
    12  )
    13  
    14  //nolint:funlen
    15  func (s Server) addRoutes(mux *http.ServeMux) {
    16  	var (
    17  		errUnknownPath      = errors.New("unknown path")
    18  		errMethodNowAllowed = errors.New("method not allowed")
    19  	)
    20  	writeUnknownPathError := func(w http.ResponseWriter, r *http.Request) {
    21  		ctx := r.Context()
    22  		log := reqid.FromContextToLogger(ctx, s.log)
    23  
    24  		utils.EncodeError(ctx, w, log, errUnknownPath, http.StatusNotFound)
    25  	}
    26  	writeMethodNowAllowedError := func(w http.ResponseWriter, r *http.Request) {
    27  		ctx := r.Context()
    28  		log := reqid.FromContextToLogger(ctx, s.log)
    29  
    30  		utils.EncodeError(ctx, w, log, errMethodNowAllowed, http.StatusMethodNotAllowed)
    31  	}
    32  
    33  	pageHandlers := pages.NewHandlers(s.db, s.log, s.config.UseEmbed, s.version, s.gitHash)
    34  
    35  	// Register the main handler. It serves pages and handles all requests with an unrecognized pattern
    36  	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    37  		var handler http.HandlerFunc
    38  		switch r.URL.Path {
    39  		case "/":
    40  			handler = pageHandlers.IndexPage
    41  		case "/months":
    42  			handler = pageHandlers.MonthsPage
    43  		case "/months/month":
    44  			handler = pageHandlers.MonthPage
    45  		case "/search/spends":
    46  			handler = pageHandlers.SearchSpendsPage
    47  		default:
    48  			writeUnknownPathError(w, r)
    49  			return
    50  		}
    51  
    52  		// Only GET requests are allowed
    53  		if r.Method != http.MethodGet {
    54  			writeMethodNowAllowedError(w, r)
    55  			return
    56  		}
    57  
    58  		handler.ServeHTTP(w, r)
    59  	})
    60  
    61  	apiHandlers := api.NewHandlers(s.db, s.log)
    62  
    63  	// Register API handlers
    64  	for pattern, routes := range map[string]map[string]http.HandlerFunc{
    65  		"/api/months/date": {
    66  			http.MethodGet: apiHandlers.GetMonthByDate,
    67  		},
    68  		"/api/incomes": {
    69  			http.MethodPost:   apiHandlers.AddIncome,
    70  			http.MethodPut:    apiHandlers.EditIncome,
    71  			http.MethodDelete: apiHandlers.RemoveIncome,
    72  		},
    73  		"/api/monthly-payments": {
    74  			http.MethodPost:   apiHandlers.AddMonthlyPayment,
    75  			http.MethodPut:    apiHandlers.EditMonthlyPayment,
    76  			http.MethodDelete: apiHandlers.RemoveMonthlyPayment,
    77  		},
    78  		"/api/spends": {
    79  			http.MethodPost:   apiHandlers.AddSpend,
    80  			http.MethodPut:    apiHandlers.EditSpend,
    81  			http.MethodDelete: apiHandlers.RemoveSpend,
    82  		},
    83  		"/api/spend-types": {
    84  			http.MethodGet:    apiHandlers.GetSpendTypes,
    85  			http.MethodPost:   apiHandlers.AddSpendType,
    86  			http.MethodPut:    apiHandlers.EditSpendType,
    87  			http.MethodDelete: apiHandlers.RemoveSpendType,
    88  		},
    89  		"/api/search/spends": {
    90  			http.MethodGet: apiHandlers.SearchSpends,
    91  		},
    92  	} {
    93  		pattern := pattern
    94  		routes := routes
    95  		mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
    96  			if r.URL.Path != pattern {
    97  				writeUnknownPathError(w, r)
    98  				return
    99  			}
   100  
   101  			handler, ok := routes[r.Method]
   102  			if !ok {
   103  				writeMethodNowAllowedError(w, r)
   104  				return
   105  			}
   106  
   107  			handler.ServeHTTP(w, r)
   108  		})
   109  	}
   110  }
   111  
   112  func (Server) addPprofRoutes(mux *http.ServeMux) {
   113  	mux.HandleFunc("/debug/pprof/", pprof.Index)
   114  	mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
   115  	mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
   116  	mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
   117  	mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
   118  }