stash/vendor/github.com/99designs/gqlgen/graphql/handler/server.go
WithoutPants 30809e16fa
Update go dependencies (#3480)
* Bump golang.org/x/text from 0.3.7 to 0.3.8

Bumps [golang.org/x/text](https://github.com/golang/text) from 0.3.7 to 0.3.8.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.3.7...v0.3.8)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update go dependencies

* Update x/net

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-28 08:26:14 +11:00

186 lines
4.7 KiB
Go

package handler
import (
"context"
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/executor"
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/99designs/gqlgen/graphql/handler/lru"
"github.com/99designs/gqlgen/graphql/handler/transport"
"github.com/vektah/gqlparser/v2/gqlerror"
)
type (
Server struct {
transports []graphql.Transport
exec *executor.Executor
}
)
func New(es graphql.ExecutableSchema) *Server {
return &Server{
exec: executor.New(es),
}
}
func NewDefaultServer(es graphql.ExecutableSchema) *Server {
srv := New(es)
srv.AddTransport(transport.Websocket{
KeepAlivePingInterval: 10 * time.Second,
})
srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{})
srv.AddTransport(transport.POST{})
srv.AddTransport(transport.MultipartForm{})
srv.SetQueryCache(lru.New(1000))
srv.Use(extension.Introspection{})
srv.Use(extension.AutomaticPersistedQuery{
Cache: lru.New(100),
})
return srv
}
func (s *Server) AddTransport(transport graphql.Transport) {
s.transports = append(s.transports, transport)
}
func (s *Server) SetErrorPresenter(f graphql.ErrorPresenterFunc) {
s.exec.SetErrorPresenter(f)
}
func (s *Server) SetRecoverFunc(f graphql.RecoverFunc) {
s.exec.SetRecoverFunc(f)
}
func (s *Server) SetQueryCache(cache graphql.Cache) {
s.exec.SetQueryCache(cache)
}
func (s *Server) Use(extension graphql.HandlerExtension) {
s.exec.Use(extension)
}
// AroundFields is a convenience method for creating an extension that only implements field middleware
func (s *Server) AroundFields(f graphql.FieldMiddleware) {
s.exec.AroundFields(f)
}
// AroundRootFields is a convenience method for creating an extension that only implements field middleware
func (s *Server) AroundRootFields(f graphql.RootFieldMiddleware) {
s.exec.AroundRootFields(f)
}
// AroundOperations is a convenience method for creating an extension that only implements operation middleware
func (s *Server) AroundOperations(f graphql.OperationMiddleware) {
s.exec.AroundOperations(f)
}
// AroundResponses is a convenience method for creating an extension that only implements response middleware
func (s *Server) AroundResponses(f graphql.ResponseMiddleware) {
s.exec.AroundResponses(f)
}
func (s *Server) getTransport(r *http.Request) graphql.Transport {
for _, t := range s.transports {
if t.Supports(r) {
return t
}
}
return nil
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
err := s.exec.PresentRecoveredError(r.Context(), err)
gqlErr, _ := err.(*gqlerror.Error)
resp := &graphql.Response{Errors: []*gqlerror.Error{gqlErr}}
b, _ := json.Marshal(resp)
w.WriteHeader(http.StatusUnprocessableEntity)
w.Write(b)
}
}()
r = r.WithContext(graphql.StartOperationTrace(r.Context()))
transport := s.getTransport(r)
if transport == nil {
sendErrorf(w, http.StatusBadRequest, "transport not supported")
return
}
transport.Do(w, r, s.exec)
}
func sendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) {
w.WriteHeader(code)
b, err := json.Marshal(&graphql.Response{Errors: errors})
if err != nil {
panic(err)
}
w.Write(b)
}
func sendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) {
sendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)})
}
type OperationFunc func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler
func (r OperationFunc) ExtensionName() string {
return "InlineOperationFunc"
}
func (r OperationFunc) Validate(schema graphql.ExecutableSchema) error {
if r == nil {
return fmt.Errorf("OperationFunc can not be nil")
}
return nil
}
func (r OperationFunc) InterceptOperation(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler {
return r(ctx, next)
}
type ResponseFunc func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response
func (r ResponseFunc) ExtensionName() string {
return "InlineResponseFunc"
}
func (r ResponseFunc) Validate(schema graphql.ExecutableSchema) error {
if r == nil {
return fmt.Errorf("ResponseFunc can not be nil")
}
return nil
}
func (r ResponseFunc) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response {
return r(ctx, next)
}
type FieldFunc func(ctx context.Context, next graphql.Resolver) (res interface{}, err error)
func (f FieldFunc) ExtensionName() string {
return "InlineFieldFunc"
}
func (f FieldFunc) Validate(schema graphql.ExecutableSchema) error {
if f == nil {
return fmt.Errorf("FieldFunc can not be nil")
}
return nil
}
func (f FieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error) {
return f(ctx, next)
}