-
Notifications
You must be signed in to change notification settings - Fork 0
/
router.go
135 lines (119 loc) · 3.58 KB
/
router.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package router
import (
"fmt"
"strings"
"github.com/kodflow/kitsune/src/internal/core/server/transport"
"github.com/kodflow/kitsune/src/internal/core/server/transport/proto/generated"
"github.com/kodflow/kitsune/src/internal/kernel/observability/logger"
)
func (r *Router) Register(epi *EndPoint) error {
if epi == nil {
return (fmt.Errorf("endpoint is not defined"))
} else if !epi.isRootEndpoint() {
return (fmt.Errorf("%v is not a root endpoint", epi.Endpoint))
}
r.endpoint = epi
logger.Info("Register endpoint: ")
for _, e := range epi.traverse() {
url := e.URL()
for _, method := range e.options {
logger.Infof("%v %v", method, url)
}
}
return nil
}
// Resolve process the request and applies appropriate handlers
//
// This function takes a router and an exchange object. It resolves the endpoint from the request,
// then applies the corresponding handlers based on the request method.
//
// Parameters:
// - exchange: *transport.Exchange The exchange object containing request and response.
//
// Returns:
// - err: error The error encountered during processing, if any.
func (r *Router) Resolve(exchange *transport.Exchange) {
//time.Sleep(100 * time.Millisecond)
req := exchange.Request()
res := exchange.Response()
if r.endpoint == nil {
res.Status = 404
return
}
// Simplify the extraction of endpoint names
endpointNames := simplifyEndpointNames(req.Endpoint)
var endpoint *EndPoint
var ok bool
// Find the appropriate endpoint
for _, name := range endpointNames {
endpoint, ok = r.getEndpoint(endpoint, name)
if !ok {
return
}
}
// Process with the found endpoint
if endpoint != nil {
r.processEndpoint(endpoint, req, res)
}
}
// simplifyEndpointNames trims and splits the endpoint string
//
// Parameters:
// - endpointStr: string The endpoint URL string.
//
// Returns:
// - []string The sliced parts of the endpoint.
func simplifyEndpointNames(endpointStr string) []string {
return strings.Split(strings.Trim(endpointStr, "/"), "/")
}
// getEndpoint finds the nested endpoint based on the name
//
// Parameters:
// - currentEndpoint: *EndPoint The current endpoint to start the search from.
// - name: string The name of the next endpoint to find.
//
// Returns:
// - *EndPoint The found endpoint or nil.
// - bool Indicates if the endpoint was found.
func (r *Router) getEndpoint(currentEndpoint *EndPoint, name string) (*EndPoint, bool) {
if currentEndpoint == nil {
ep, ok := r.endpoint.subs[name]
return ep, ok
}
ep, ok := currentEndpoint.subs[name]
return ep, ok
}
// processEndpoint applies handlers for the endpoint based on the request method
//
// Parameters:
// - endpoint: *EndPoint The endpoint to process.
// - req: *Request The request object.
// - res: *Response The response object.
//
// Returns:
// - error The error encountered during processing, if any.
func (r *Router) processEndpoint(endpoint *EndPoint, req *generated.Request, res *generated.Response) error {
if handlers, ok := endpoint.handlers[req.Method]; ok {
for _, handler := range handlers {
if err := handler(req, res); err != nil {
return err
}
}
}
return nil
}
// Router represents your API.
// It manages the association of URL paths with their corresponding handlers based on
// HTTP methods like GET, POST, PUT, PATCH, and DELETE. The Router also keeps track of
// whether it is deprecated.
type Router struct {
endpoint *EndPoint
}
// MakeRouter creates and returns a new instance of Router.
// This function initializes a Router with its default values.
//
// Returns:
// - *Router: A new instance of Router.
func MakeRouter() *Router {
return &Router{}
}