enhance cache
This commit is contained in:
parent
1a0904e873
commit
24f770d6cf
@ -2,6 +2,7 @@ package app
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -10,7 +11,9 @@ import (
|
|||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getTokenFromHeader(authHeader string) (string, error) {
|
func getTokenFromHeader(r *http.Request) (string, error) {
|
||||||
|
|
||||||
|
authHeader := r.Header.Get("Authorization")
|
||||||
|
|
||||||
if authHeader == "" {
|
if authHeader == "" {
|
||||||
return "", fmt.Errorf("there is no authorization header provided")
|
return "", fmt.Errorf("there is no authorization header provided")
|
||||||
@ -25,6 +28,17 @@ func getTokenFromHeader(authHeader string) (string, error) {
|
|||||||
return strings.TrimSpace(authSlice[1]), nil
|
return strings.TrimSpace(authSlice[1]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTokenFromCookie(r *http.Request) (string, error) {
|
||||||
|
|
||||||
|
cookie, err := r.Cookie("app-access-token")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("there is no authorization cookie provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimSpace(cookie.Value), nil
|
||||||
|
}
|
||||||
|
|
||||||
func getUserFromToken(tokenString string) (*models.UserJWT, error) {
|
func getUserFromToken(tokenString string) (*models.UserJWT, error) {
|
||||||
token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
|
token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
|
||||||
|
|
||||||
|
|||||||
@ -20,8 +20,8 @@ func ExpiryMiddleware(ctx context.Context, next graphql.ResponseHandler) *graphq
|
|||||||
// AuthMiddleware parses JWT token and injects user context for HTTP requests
|
// AuthMiddleware parses JWT token and injects user context for HTTP requests
|
||||||
func AuthMiddleware(next http.Handler) http.Handler {
|
func AuthMiddleware(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
authHeader := r.Header.Get("Authorization")
|
|
||||||
tokenStr, err := getTokenFromHeader(authHeader)
|
tokenStr, err := getTokenFromHeader(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx := SetStatus(r.Context(), err.Error())
|
ctx := SetStatus(r.Context(), err.Error())
|
||||||
next.ServeHTTP(rw, r.WithContext(ctx))
|
next.ServeHTTP(rw, r.WithContext(ctx))
|
||||||
|
|||||||
33
helpers/cache.go
Normal file
33
helpers/cache.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cache struct {
|
||||||
|
client redis.UniversalClient
|
||||||
|
ttl time.Duration
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCache(client redis.UniversalClient, ttl time.Duration, prefix string) (*Cache, error) {
|
||||||
|
return &Cache{client: client, ttl: ttl, prefix: prefix}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) Add(ctx context.Context, key string, value string) {
|
||||||
|
log.Printf("Adding key %s to cache with value %s", key, value)
|
||||||
|
c.client.Set(ctx, c.prefix+key, value, c.ttl)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) Get(ctx context.Context, key string) (string, bool) {
|
||||||
|
s, err := c.client.Get(ctx, c.prefix+key).Result()
|
||||||
|
if err != nil {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
log.Printf("Retrieved key %s from cache with value %s", key, s)
|
||||||
|
return s, true
|
||||||
|
}
|
||||||
@ -1,7 +1,5 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import "go.mongodb.org/mongo-driver/bson/primitive"
|
|
||||||
|
|
||||||
func (m Todo) Validate() []error {
|
func (m Todo) Validate() []error {
|
||||||
|
|
||||||
errors := []error{}
|
errors := []error{}
|
||||||
@ -13,10 +11,6 @@ func (m Todo) Validate() []error {
|
|||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Todo) getId() primitive.ObjectID {
|
|
||||||
return m.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Todo) validate() []error {
|
func (t *Todo) validate() []error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
18
router.go
18
router.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@ -9,6 +10,7 @@ import (
|
|||||||
"git.farahty.com/nimer/go-mongo/controllers"
|
"git.farahty.com/nimer/go-mongo/controllers"
|
||||||
"git.farahty.com/nimer/go-mongo/directives"
|
"git.farahty.com/nimer/go-mongo/directives"
|
||||||
"git.farahty.com/nimer/go-mongo/generated"
|
"git.farahty.com/nimer/go-mongo/generated"
|
||||||
|
"git.farahty.com/nimer/go-mongo/helpers"
|
||||||
"github.com/99designs/gqlgen/graphql/handler"
|
"github.com/99designs/gqlgen/graphql/handler"
|
||||||
"github.com/99designs/gqlgen/graphql/handler/extension"
|
"github.com/99designs/gqlgen/graphql/handler/extension"
|
||||||
"github.com/99designs/gqlgen/graphql/handler/transport"
|
"github.com/99designs/gqlgen/graphql/handler/transport"
|
||||||
@ -50,6 +52,13 @@ func createRouter(graphqlServer http.Handler) chi.Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createGraphqlServer(redisClient *redis.Client) http.Handler {
|
func createGraphqlServer(redisClient *redis.Client) http.Handler {
|
||||||
|
|
||||||
|
cache, err := helpers.NewCache(redisClient, 24*time.Hour, "apq:")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("cannot create APQ redis cache: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Setup gqlgen with resolvers and Redis client
|
// Setup gqlgen with resolvers and Redis client
|
||||||
schema := generated.Config{
|
schema := generated.Config{
|
||||||
Resolvers: &resolvers.Resolver{
|
Resolvers: &resolvers.Resolver{
|
||||||
@ -78,14 +87,7 @@ func createGraphqlServer(redisClient *redis.Client) http.Handler {
|
|||||||
srv.AddTransport(transport.POST{})
|
srv.AddTransport(transport.POST{})
|
||||||
srv.AddTransport(transport.MultipartForm{})
|
srv.AddTransport(transport.MultipartForm{})
|
||||||
|
|
||||||
// Optional: Enable persisted queries or caching
|
srv.Use(extension.AutomaticPersistedQuery{Cache: cache})
|
||||||
// srv.Use(extension.AutomaticPersistedQuery{
|
|
||||||
// Cache: lru.New(100),
|
|
||||||
// })
|
|
||||||
// srv.SetQueryCache(lru.New(1000))
|
|
||||||
|
|
||||||
// Enable introspection for Playground
|
|
||||||
srv.Use(extension.Introspection{})
|
|
||||||
|
|
||||||
// Apply global middleware
|
// Apply global middleware
|
||||||
srv.AroundRootFields(app.RootFieldsAuthorizer) // Check for @auth at root fields
|
srv.AroundRootFields(app.RootFieldsAuthorizer) // Check for @auth at root fields
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user