refelct the format from the proposal
This commit is contained in:
parent
c340ed9ed5
commit
4fcda01738
1 changed files with 88 additions and 82 deletions
170
pkg/op/server.go
170
pkg/op/server.go
|
@ -41,94 +41,18 @@ func (e StatusError) Is(err error) bool {
|
||||||
e.statusCode == target.statusCode
|
e.statusCode == target.statusCode
|
||||||
}
|
}
|
||||||
|
|
||||||
type Request[T any] struct {
|
// Server describes the interface that needs to be implemented to serve
|
||||||
Method string
|
// OpenID Connect and Oauth2 standard requests.
|
||||||
URL *url.URL
|
|
||||||
Header http.Header
|
|
||||||
Form url.Values
|
|
||||||
PostForm url.Values
|
|
||||||
Data *T
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRequest[T any](r *http.Request, data *T) *Request[T] {
|
|
||||||
return &Request[T]{
|
|
||||||
Method: r.Method,
|
|
||||||
URL: r.URL,
|
|
||||||
Header: r.Header,
|
|
||||||
Form: r.Form,
|
|
||||||
PostForm: r.PostForm,
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientRequest is a Request with a verified client attached to it.
|
|
||||||
// Methods the recieve this argument may assume the client was authenticated,
|
|
||||||
// or verified to be a public client.
|
|
||||||
type ClientRequest[T any] struct {
|
|
||||||
*Request[T]
|
|
||||||
Client Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func newClientRequest[T any](r *http.Request, data *T, client Client) *ClientRequest[T] {
|
|
||||||
return &ClientRequest[T]{
|
|
||||||
Request: newRequest[T](r, data),
|
|
||||||
Client: client,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Response struct {
|
|
||||||
// Header map will be merged with the
|
|
||||||
// header on the [http.ResponseWriter].
|
|
||||||
Header http.Header
|
|
||||||
|
|
||||||
// Data will be JSON marshalled to
|
|
||||||
// the response body.
|
|
||||||
// We allow any type, so that implementers
|
|
||||||
// can extend the standard types as they wish.
|
|
||||||
// However, each method will recommend which
|
|
||||||
// (base) type to use as model, in order to
|
|
||||||
// be complient with the standards.
|
|
||||||
Data any
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewResponse(data any) *Response {
|
|
||||||
return &Response{
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (resp *Response) writeOut(w http.ResponseWriter) {
|
|
||||||
gu.MapMerge(resp.Header, w.Header())
|
|
||||||
json.NewEncoder(w).Encode(resp.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Redirect struct {
|
|
||||||
URL url.URL
|
|
||||||
Params url.Values
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server describes the inferface that needs to be implemented to serve
|
|
||||||
// openID Connect and Oauth2 standard requests.
|
|
||||||
//
|
//
|
||||||
// Methods are called after the HTTP route is resolved and
|
// Methods are called after the HTTP route is resolved and
|
||||||
// the request body is parsed into the Request's Data field.
|
// the request body is parsed into the Request's Data field.
|
||||||
// When a method is called, it can be assumed that required fields,
|
// When a method is called, it can be assumed that required fields,
|
||||||
// as described in their relavant standard, are validated already.
|
// as described in their relevant standard, are validated already.
|
||||||
// The Response Data field may be of any type to allow flexibilty
|
// The Response Data field may be of any type to allow flexibility
|
||||||
// to extend responses with custom fields. There are however requirements
|
// to extend responses with custom fields. There are however requirements
|
||||||
// in the standards regarding the repsonse models. Where applicable
|
// in the standards regarding the response models. Where applicable
|
||||||
// the method documentation gives a recommodated type which can be used
|
// the method documentation gives a recommended type which can be used
|
||||||
// directly or extended upon.
|
// directly or extended upon.
|
||||||
//
|
|
||||||
// In short it is the scope of this framework to:
|
|
||||||
// - Route requests to their methods;
|
|
||||||
// - Parse request data into a type that represents the model from the standards;
|
|
||||||
// - Validate required fields in the request;
|
|
||||||
// - Provide utility functions that help implementors build the response;
|
|
||||||
//
|
|
||||||
// It is in the scope of the implementor:
|
|
||||||
// - Handle the request data to obtain or modify state in their storage / database;
|
|
||||||
// - Implement the business logic that is needed to build the response;
|
|
||||||
type Server interface {
|
type Server interface {
|
||||||
// Health should return a status of "ok" once the Server is listining.
|
// Health should return a status of "ok" once the Server is listining.
|
||||||
// The recommended Response Data type is [Status].
|
// The recommended Response Data type is [Status].
|
||||||
|
@ -240,6 +164,88 @@ type Server interface {
|
||||||
mustImpl()
|
mustImpl()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Request contains the [http.Request] informational fields
|
||||||
|
// and parsed Data from the request body (POST) or URL parameters (GET).
|
||||||
|
// Data can be assumed to be validated according to the applicable
|
||||||
|
// standard for the specific endpoints.
|
||||||
|
type Request[T any] struct {
|
||||||
|
Method string
|
||||||
|
URL *url.URL
|
||||||
|
Header http.Header
|
||||||
|
Form url.Values
|
||||||
|
PostForm url.Values
|
||||||
|
Data *T
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRequest[T any](r *http.Request, data *T) *Request[T] {
|
||||||
|
return &Request[T]{
|
||||||
|
Method: r.Method,
|
||||||
|
URL: r.URL,
|
||||||
|
Header: r.Header,
|
||||||
|
Form: r.Form,
|
||||||
|
PostForm: r.PostForm,
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientRequest is a Request with a verified client attached to it.
|
||||||
|
// Methods the recieve this argument may assume the client was authenticated,
|
||||||
|
// or verified to be a public client.
|
||||||
|
type ClientRequest[T any] struct {
|
||||||
|
*Request[T]
|
||||||
|
Client Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func newClientRequest[T any](r *http.Request, data *T, client Client) *ClientRequest[T] {
|
||||||
|
return &ClientRequest[T]{
|
||||||
|
Request: newRequest[T](r, data),
|
||||||
|
Client: client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
// Header map will be merged with the
|
||||||
|
// header on the [http.ResponseWriter].
|
||||||
|
Header http.Header
|
||||||
|
|
||||||
|
// Data will be JSON marshaled to
|
||||||
|
// the response body.
|
||||||
|
// We allow any type, so that implementations
|
||||||
|
// can extend the standard types as they wish.
|
||||||
|
// However, each method will recommend which
|
||||||
|
// (base) type to use as model, in order to
|
||||||
|
// be complaint with the standards.
|
||||||
|
Data any
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResponse(data any) *Response {
|
||||||
|
return &Response{
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (resp *Response) writeOut(w http.ResponseWriter) {
|
||||||
|
gu.MapMerge(resp.Header, w.Header())
|
||||||
|
json.NewEncoder(w).Encode(resp.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect is a special response type which will
|
||||||
|
// initiate a [http.StatusFound] redirect.
|
||||||
|
// The Params field will be encoded and set to the
|
||||||
|
// URL's RawQuery field before building the URL.
|
||||||
|
//
|
||||||
|
// If the RawQuery contains values that need to persist,
|
||||||
|
// the implementation should parse them into Params and
|
||||||
|
// add request specific values after.
|
||||||
|
type Redirect struct {
|
||||||
|
// Header map will be merged with the
|
||||||
|
// header on the [http.ResponseWriter].
|
||||||
|
Header http.Header
|
||||||
|
|
||||||
|
URL url.URL
|
||||||
|
Params url.Values
|
||||||
|
}
|
||||||
|
|
||||||
type UnimplementedServer struct{}
|
type UnimplementedServer struct{}
|
||||||
|
|
||||||
// UnimplementedStatusCode is the statuscode returned for methods
|
// UnimplementedStatusCode is the statuscode returned for methods
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue