-
-
Notifications
You must be signed in to change notification settings - Fork 27
/
api.go
96 lines (80 loc) · 2.88 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
package cmd
import (
"fmt"
"net/http"
"os"
"strings"
"entgo.io/contrib/entgql"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/99designs/gqlgen/graphql/playground"
sentryhttp "github.com/getsentry/sentry-go/http"
"github.com/go-chi/chi/v5"
_ "github.com/lib/pq"
"github.com/rs/cors"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"go.opentelemetry.io/otel"
"atomys.codes/stud42/internal/api"
modelsutils "atomys.codes/stud42/internal/models"
"atomys.codes/stud42/internal/pkg/searchengine"
"atomys.codes/stud42/pkg/otelgql"
)
var (
apiPortFlag *string
playgroudActive *bool
)
// apiCmd represents the api command
var apiCmd = &cobra.Command{
Use: "api",
Short: "Serve the API in production",
PreRun: func(cmd *cobra.Command, args []string) {
if err := modelsutils.Connect(); err != nil {
log.Fatal().Err(err).Msg("failed to connect to database")
}
if err := modelsutils.Migrate(); err != nil {
log.Fatal().Err(err).Msg("failed to migrate database")
}
searchengine.Initizialize()
},
Run: func(cmd *cobra.Command, args []string) {
tracer := otel.GetTracerProvider().Tracer("graphql-api")
srv := handler.NewDefaultServer(api.NewSchema(modelsutils.Client(), tracer))
// srv.SetRecoverFunc(func(ctx context.Context, err interface{}) error {
// // notify bug tracker...
// log.Error().Err(err.(error)).Msg("unhandled error")
// return gqlerror.Errorf("Internal server error!")
// })
srv.Use(entgql.Transactioner{TxOpener: modelsutils.Client()})
srv.Use(extension.FixedComplexityLimit(50))
srv.Use(otelgql.Middleware(tracer))
router := chi.NewRouter()
router.Use(cors.New(cors.Options{
AllowedOrigins: strings.Split(os.Getenv("CORS_ORIGIN"), ","),
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "Sentry-Trace"},
AllowCredentials: true,
Debug: os.Getenv("DEBUG") == "true",
}).Handler)
router.Use(api.AuthzByPolicyMiddleware)
router.Use(api.AuthenticationMiddleware)
if os.Getenv("DEBUG") == "true" {
router.Use(api.LoggingMiddleware)
}
if *playgroudActive {
router.Handle("/", playground.Handler("GraphQL playground", "/graphql"))
log.Info().Msgf("connect to http://localhost:%s/ for GraphQL playground", *apiPortFlag)
}
sentryHandler := sentryhttp.New(sentryhttp.Options{
Repanic: false,
WaitForDelivery: true,
})
router.Handle("/graphql", sentryHandler.Handle(srv))
log.Fatal().Err(http.ListenAndServe(fmt.Sprintf(":%s", *apiPortFlag), router)).Msg("Error during server start")
},
}
func init() {
serveCmd.AddCommand(apiCmd)
apiPortFlag = apiCmd.Flags().StringP("port", "p", "4000", "port used to serve the interface")
playgroudActive = apiCmd.Flags().BoolP("GraphQLi", "g", false, "enable playground")
}