-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.go
114 lines (98 loc) · 3.08 KB
/
api.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
package auth
import (
"net/http"
"github.com/julienschmidt/httprouter"
"github.com/neuronlabs/neuron/auth"
"github.com/neuronlabs/neuron/codec"
"github.com/neuronlabs/neuron/controller"
"github.com/neuronlabs/neuron/errors"
"github.com/neuronlabs/neuron/mapping"
"github.com/neuronlabs/neuron/server"
"github.com/neuronlabs/neuron-extensions/codec/json"
"github.com/neuronlabs/neuron-extensions/server/http/httputil"
"github.com/neuronlabs/neuron-extensions/server/http/log"
)
// API is an API for the accounts operations.
type API struct {
Options *Options
Authenticator auth.Authenticator
Tokener auth.Tokener
Endpoints []*server.Endpoint
// model is account model structure.
model *mapping.ModelStruct
defaultHandler *DefaultHandler
serverOptions server.Options
}
// New creates account API.
func New(options ...Option) (*API, error) {
a := &API{
Options: defaultOptions(),
defaultHandler: &DefaultHandler{},
}
for _, option := range options {
option(a.Options)
}
if a.Options.AccountModel == nil {
return nil, errors.Wrap(auth.ErrAccountModelNotDefined, "provided no account model for the account service")
}
a.defaultHandler.Account = a.Options.AccountModel
return a, nil
}
// InitializeAPI implements server/http.API interface.
func (a *API) InitializeAPI(options server.Options) error {
a.serverOptions = options
// Check authenticator.
a.Authenticator = options.Authenticator
if a.Authenticator == nil {
return errors.Wrap(auth.ErrInitialization, "provided nil authenticator for the service")
}
tokener, ok := options.Authenticator.(auth.Tokener)
if !ok {
return errors.Wrap(auth.ErrInitialization, "provided authenticator is not a tokener")
}
a.Tokener = tokener
mStruct, err := a.serverOptions.Controller.ModelStruct(a.Options.AccountModel)
if err != nil {
return err
}
a.model = mStruct
// Initialize default handler.
if err := a.defaultHandler.Initialize(options.Controller); err != nil {
return err
}
// Initialize handler if needed.
if initializer, ok := a.Options.AccountHandler.(interface {
Initialize(c *controller.Controller) error
}); ok {
if err := initializer.Initialize(options.Controller); err != nil {
return err
}
}
return nil
}
// GetEndpoints implements server.EndpointsGetter.
func (a *API) GetEndpoints() []*server.Endpoint {
return a.Endpoints
}
// SetRoutes sets the router
func (a *API) SetRoutes(router *httprouter.Router) error {
return nil
}
func (a *API) marshalErrors(rw http.ResponseWriter, status int, err error) {
httpErrors := httputil.MapError(err)
a.setContentType(rw)
// If no status is defined - set default from the errors.
if status == 0 {
status = codec.MultiError(httpErrors).Status()
}
// Write status to the header.
rw.WriteHeader(status)
// Marshal errors into response writer.
marshalError := json.GetCodec(a.serverOptions.Controller).MarshalErrors(rw, httpErrors...)
if err != nil {
log.Errorf("Marshaling errors: '%v' failed: %v", httpErrors, marshalError)
}
}
func (a *API) setContentType(rw http.ResponseWriter) {
rw.Header().Set("Content-Type", json.MimeType)
}