BLOG-43 feat: get all posts
All checks were successful
Frontend CI / build (push) Successful in 1m56s

This commit is contained in:
SquidSpirit 2025-03-28 00:02:34 +08:00
parent a9081734b3
commit a4394eea9e
26 changed files with 726 additions and 111 deletions

View File

@ -1,28 +1,39 @@
package main package main
import ( import (
"database/sql"
"log" "log"
"net/http" "net/http"
"os"
"git.squidspirit.com/squid/blog.git/backend/internal/framework/graph" "git.squidspirit.com/squid/blog.git/backend/internal/adapter/gateway"
"git.squidspirit.com/squid/blog.git/backend/internal/application"
"git.squidspirit.com/squid/blog.git/backend/internal/framework/api/graph"
"git.squidspirit.com/squid/blog.git/backend/internal/framework/db/postgres"
"git.squidspirit.com/squid/blog.git/backend/internal/pkg/env"
"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/lru" "github.com/99designs/gqlgen/graphql/handler/lru"
"github.com/99designs/gqlgen/graphql/handler/transport" "github.com/99designs/gqlgen/graphql/handler/transport"
"github.com/99designs/gqlgen/graphql/playground" "github.com/99designs/gqlgen/graphql/playground"
_ "github.com/lib/pq"
"github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/ast"
) )
const defaultPort = "8080"
func main() { func main() {
port := os.Getenv("PORT") db, err := postgres.Connect(env.GetDSN())
if port == "" { if err != nil {
port = defaultPort log.Fatal(err)
} }
srv := handler.New(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})) initGraphqlHandler(createResolver(db))
port := env.GetPort()
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
func initGraphqlHandler(resolver *graph.Resolver) *handler.Server {
srv := handler.New(graph.NewExecutableSchema(graph.Config{Resolvers: resolver}))
srv.AddTransport(transport.Options{}) srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{}) srv.AddTransport(transport.GET{})
@ -38,6 +49,13 @@ func main() {
http.Handle("/", playground.Handler("GraphQL playground", "/query")) http.Handle("/", playground.Handler("GraphQL playground", "/query"))
http.Handle("/query", srv) http.Handle("/query", srv)
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) return srv
log.Fatal(http.ListenAndServe(":"+port, nil)) }
func createResolver(db *sql.DB) *graph.Resolver {
postRepo := gateway.NewPostRepo(postgres.NewPostDBService(db))
return &graph.Resolver{
GetAllPostsUseCase: application.NewGetAllPostsUseCase(postRepo),
}
} }

View File

@ -4,6 +4,8 @@ go 1.24.1
require ( require (
github.com/99designs/gqlgen v0.17.66 github.com/99designs/gqlgen v0.17.66
github.com/lib/pq v1.10.9
github.com/thoas/go-funk v0.9.3
github.com/vektah/gqlparser/v2 v2.5.22 github.com/vektah/gqlparser/v2 v2.5.22
) )
@ -11,16 +13,20 @@ require (
github.com/agnivade/levenshtein v1.2.0 // indirect github.com/agnivade/levenshtein v1.2.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sosodev/duration v1.3.1 // indirect github.com/sosodev/duration v1.3.1 // indirect
github.com/urfave/cli/v2 v2.27.5 // indirect github.com/urfave/cli/v2 v2.27.5 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/mod v0.23.0 // indirect golang.org/x/mod v0.24.0 // indirect
golang.org/x/sync v0.11.0 // indirect golang.org/x/sync v0.12.0 // indirect
golang.org/x/text v0.22.0 // indirect golang.org/x/text v0.23.0 // indirect
golang.org/x/tools v0.30.0 // indirect golang.org/x/tools v0.31.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

View File

@ -12,47 +12,68 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo=
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4=
github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/vektah/gqlparser/v2 v2.5.22 h1:yaaeJ0fu+nv1vUMW0Hl+aS1eiv1vMfapBNjpffAda1I= github.com/vektah/gqlparser/v2 v2.5.22 h1:yaaeJ0fu+nv1vUMW0Hl+aS1eiv1vMfapBNjpffAda1I=
github.com/vektah/gqlparser/v2 v2.5.22/go.mod h1:xMl+ta8a5M1Yo1A1Iwt/k7gSpscwSnHZdw7tfhEGfTM= github.com/vektah/gqlparser/v2 v2.5.22/go.mod h1:xMl+ta8a5M1Yo1A1Iwt/k7gSpscwSnHZdw7tfhEGfTM=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,6 +1,6 @@
# Where are all the schema files located? globs are supported eg src/**/*.graphqls # Where are all the schema files located? globs are supported eg src/**/*.graphqls
schema: schema:
- internal/framework/graph/*.graphqls - internal/framework/api/graph/*.graphqls
# Where should the generated server code go? # Where should the generated server code go?
exec: exec:
@ -8,7 +8,7 @@ exec:
layout: single-file # Only other option is "follow-schema," ie multi-file. layout: single-file # Only other option is "follow-schema," ie multi-file.
# Only for single-file layout: # Only for single-file layout:
filename: internal/framework/graph/generated.go filename: internal/framework/api/graph/generated.go
# Only for follow-schema layout: # Only for follow-schema layout:
# dir: graph # dir: graph
@ -27,8 +27,8 @@ exec:
# Where should any generated models go? # Where should any generated models go?
model: model:
filename: internal/framework/graph/model/models_gen.go filename: internal/adapter/controller/graphdto/dtos.go
package: model package: graphdto
# Optional: Pass in a path to a new gotpl template to use for generating the models # Optional: Pass in a path to a new gotpl template to use for generating the models
# model_template: [your/path/model.gotpl] # model_template: [your/path/model.gotpl]
@ -42,7 +42,7 @@ resolver:
# filename: graph/resolver.go # filename: graph/resolver.go
# Only for follow-schema layout: # Only for follow-schema layout:
dir: internal/framework/graph dir: internal/framework/api/graph
filename_template: "{name}.resolvers.go" filename_template: "{name}.resolvers.go"
# Optional: turn on to not generate template comments above resolvers # Optional: turn on to not generate template comments above resolvers
@ -127,10 +127,7 @@ autobind:
models: models:
ID: ID:
model: model:
- github.com/99designs/gqlgen/graphql.ID - github.com/99designs/gqlgen/graphql.Uint32
- github.com/99designs/gqlgen/graphql.Int
- github.com/99designs/gqlgen/graphql.Int64
- github.com/99designs/gqlgen/graphql.Int32
# gqlgen provides a default GraphQL UUID convenience wrapper for github.com/google/uuid # gqlgen provides a default GraphQL UUID convenience wrapper for github.com/google/uuid
# but you can override this to provide your own GraphQL UUID implementation # but you can override this to provide your own GraphQL UUID implementation
UUID: UUID:

View File

@ -1,20 +1,21 @@
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. // Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package model package graphdto
type Label struct { type Label struct {
ID string `json:"id"` ID uint32 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Color string `json:"color"` Color string `json:"color"`
} }
type Post struct { type Post struct {
ID string `json:"id"` ID uint32 `json:"id"`
Title string `json:"title"` Title string `json:"title"`
Content string `json:"content"` Content string `json:"content"`
Description string `json:"description"` Description string `json:"description"`
PreviewImageURL string `json:"previewImageUrl"` PreviewImageURL string `json:"previewImageUrl"`
Labels []*Label `json:"labels"` Labels []*Label `json:"labels"`
PublishedTime *string `json:"publishedTime,omitempty"`
} }
type Query struct { type Query struct {

View File

@ -0,0 +1,11 @@
package graphdto
import "git.squidspirit.com/squid/blog.git/backend/internal/domain"
func NewLabelDTO(labelEntity *domain.Label) *Label {
return &Label{
ID: labelEntity.ID,
Name: labelEntity.Name,
Color: labelEntity.Color,
}
}

View File

@ -0,0 +1,19 @@
package graphdto
import (
"git.squidspirit.com/squid/blog.git/backend/internal/domain"
"github.com/thoas/go-funk"
)
func NewPostDTO(entity *domain.Post) *Post {
return &Post{
ID: entity.ID,
Title: entity.Title,
Content: entity.Content,
Description: entity.Description,
PreviewImageURL: entity.PreviewImageURL,
Labels: funk.Map(entity.Labels, func(label *domain.Label) *Label {
return NewLabelDTO(label)
}).([]*Label),
}
}

View File

@ -0,0 +1,33 @@
package controller
import (
"git.squidspirit.com/squid/blog.git/backend/internal/adapter/controller/graphdto"
"git.squidspirit.com/squid/blog.git/backend/internal/application"
"git.squidspirit.com/squid/blog.git/backend/internal/domain"
"github.com/thoas/go-funk"
)
type QueryPostsController interface {
Handle() ([]*graphdto.Post, error)
}
type queryPostsControllerImpl struct {
getAllPostsUseCase application.GetAllPostsUseCase
}
func NewQueryPostsController(getAllPostsUseCase application.GetAllPostsUseCase) QueryPostsController {
return &queryPostsControllerImpl{
getAllPostsUseCase: getAllPostsUseCase,
}
}
func (c *queryPostsControllerImpl) Handle() ([]*graphdto.Post, error) {
entities, err := c.getAllPostsUseCase.Execute()
if err != nil {
return nil, err
}
return funk.Map(entities, func(entity *domain.Post) *graphdto.Post {
return graphdto.NewPostDTO(entity)
}).([]*graphdto.Post), nil
}

View File

@ -0,0 +1,23 @@
package dbdto
import (
"time"
"git.squidspirit.com/squid/blog.git/backend/internal/domain"
)
type Label struct {
ID uint32 `json:"id"`
Name string `json:"name"`
Color string `json:"color"`
CreatedTime time.Time
UpdatedTime time.Time
}
func (l *Label) ToEntity() *domain.Label {
return &domain.Label{
ID: l.ID,
Name: l.Name,
Color: l.Color,
}
}

View File

@ -0,0 +1,34 @@
package dbdto
import (
"time"
"git.squidspirit.com/squid/blog.git/backend/internal/domain"
"github.com/thoas/go-funk"
)
type Post struct {
ID uint32
Title string
Content string
Description string
PreviewImageURL string
Labels []*Label
PublishedTime *time.Time
CreatedTime time.Time
UpdatedTime time.Time
}
func (p *Post) ToEntity() *domain.Post {
return &domain.Post{
ID: p.ID,
Title: p.Title,
Content: p.Content,
Description: p.Description,
PreviewImageURL: p.PreviewImageURL,
Labels: funk.Map(p.Labels, func(label *Label) *domain.Label {
return label.ToEntity()
}).([]*domain.Label),
PublishedTime: p.PublishedTime,
}
}

View File

@ -0,0 +1,34 @@
package gateway
import (
"git.squidspirit.com/squid/blog.git/backend/internal/adapter/gateway/dbdto"
"git.squidspirit.com/squid/blog.git/backend/internal/application"
"git.squidspirit.com/squid/blog.git/backend/internal/domain"
"github.com/thoas/go-funk"
)
type postRepo struct {
dbService PostDBService
}
type PostDBService interface {
QueryAll() ([]*dbdto.Post, error)
}
func NewPostRepo(dbService PostDBService) application.PostRepo {
return &postRepo{dbService}
}
func (r *postRepo) GetAll() ([]*domain.Post, error) {
postDtos, err := r.dbService.QueryAll()
if err != nil {
return nil, err
}
return funk.Map(postDtos, func(postDto *dbdto.Post) *domain.Post {
return postDto.ToEntity()
}).([]*domain.Post), nil
}
func (r *postRepo) GetByID(id int) (*domain.Post, error) {
panic("unimplemented")
}

View File

@ -0,0 +1,21 @@
package application
import "git.squidspirit.com/squid/blog.git/backend/internal/domain"
type GetAllPostsUseCase interface {
Execute() ([]*domain.Post, error)
}
type getAllPostsUseCaseImpl struct {
postRepo PostRepo
}
func NewGetAllPostsUseCase(postRepo PostRepo) GetAllPostsUseCase {
return &getAllPostsUseCaseImpl{
postRepo: postRepo,
}
}
func (uc *getAllPostsUseCaseImpl) Execute() ([]*domain.Post, error) {
return uc.postRepo.GetAll()
}

View File

@ -0,0 +1,7 @@
package application
import "git.squidspirit.com/squid/blog.git/backend/internal/domain"
type LabelRepo interface {
GetByIDs(ids []int) ([]*domain.Label, error)
}

View File

@ -0,0 +1,8 @@
package application
import "git.squidspirit.com/squid/blog.git/backend/internal/domain"
type PostRepo interface {
GetAll() ([]*domain.Post, error)
GetByID(id int) (*domain.Post, error)
}

View File

@ -0,0 +1,7 @@
package domain
type Label struct {
ID uint32
Name string
Color string
}

View File

@ -0,0 +1,13 @@
package domain
import "time"
type Post struct {
ID uint32
Title string
Content string
Description string
PreviewImageURL string
Labels []*Label
PublishedTime *time.Time
}

View File

@ -12,7 +12,7 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"git.squidspirit.com/squid/blog.git/backend/internal/framework/graph/model" "git.squidspirit.com/squid/blog.git/backend/internal/adapter/controller/graphdto"
"github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/introspection" "github.com/99designs/gqlgen/graphql/introspection"
gqlparser "github.com/vektah/gqlparser/v2" gqlparser "github.com/vektah/gqlparser/v2"
@ -58,18 +58,21 @@ type ComplexityRoot struct {
ID func(childComplexity int) int ID func(childComplexity int) int
Labels func(childComplexity int) int Labels func(childComplexity int) int
PreviewImageURL func(childComplexity int) int PreviewImageURL func(childComplexity int) int
PublishedTime func(childComplexity int) int
Title func(childComplexity int) int Title func(childComplexity int) int
} }
Query struct { Query struct {
Post func(childComplexity int, id string) int Label func(childComplexity int, id uint32) int
Post func(childComplexity int, id uint32) int
Posts func(childComplexity int) int Posts func(childComplexity int) int
} }
} }
type QueryResolver interface { type QueryResolver interface {
Posts(ctx context.Context) ([]*model.Post, error) Posts(ctx context.Context) ([]*graphdto.Post, error)
Post(ctx context.Context, id string) (*model.Post, error) Post(ctx context.Context, id uint32) (*graphdto.Post, error)
Label(ctx context.Context, id uint32) (*graphdto.Label, error)
} }
type executableSchema struct { type executableSchema struct {
@ -147,6 +150,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Post.PreviewImageURL(childComplexity), true return e.complexity.Post.PreviewImageURL(childComplexity), true
case "Post.publishedTime":
if e.complexity.Post.PublishedTime == nil {
break
}
return e.complexity.Post.PublishedTime(childComplexity), true
case "Post.title": case "Post.title":
if e.complexity.Post.Title == nil { if e.complexity.Post.Title == nil {
break break
@ -154,6 +164,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Post.Title(childComplexity), true return e.complexity.Post.Title(childComplexity), true
case "Query.label":
if e.complexity.Query.Label == nil {
break
}
args, err := ec.field_Query_label_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Query.Label(childComplexity, args["id"].(uint32)), true
case "Query.post": case "Query.post":
if e.complexity.Query.Post == nil { if e.complexity.Query.Post == nil {
break break
@ -164,7 +186,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return 0, false return 0, false
} }
return e.complexity.Query.Post(childComplexity, args["id"].(string)), true return e.complexity.Query.Post(childComplexity, args["id"].(uint32)), true
case "Query.posts": case "Query.posts":
if e.complexity.Query.Posts == nil { if e.complexity.Query.Posts == nil {
@ -304,6 +326,29 @@ func (ec *executionContext) field_Query___type_argsName(
return zeroVal, nil return zeroVal, nil
} }
func (ec *executionContext) field_Query_label_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
args := map[string]any{}
arg0, err := ec.field_Query_label_argsID(ctx, rawArgs)
if err != nil {
return nil, err
}
args["id"] = arg0
return args, nil
}
func (ec *executionContext) field_Query_label_argsID(
ctx context.Context,
rawArgs map[string]any,
) (uint32, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id"))
if tmp, ok := rawArgs["id"]; ok {
return ec.unmarshalNID2uint32(ctx, tmp)
}
var zeroVal uint32
return zeroVal, nil
}
func (ec *executionContext) field_Query_post_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { func (ec *executionContext) field_Query_post_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error var err error
args := map[string]any{} args := map[string]any{}
@ -317,13 +362,13 @@ func (ec *executionContext) field_Query_post_args(ctx context.Context, rawArgs m
func (ec *executionContext) field_Query_post_argsID( func (ec *executionContext) field_Query_post_argsID(
ctx context.Context, ctx context.Context,
rawArgs map[string]any, rawArgs map[string]any,
) (string, error) { ) (uint32, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("id"))
if tmp, ok := rawArgs["id"]; ok { if tmp, ok := rawArgs["id"]; ok {
return ec.unmarshalNID2string(ctx, tmp) return ec.unmarshalNID2uint32(ctx, tmp)
} }
var zeroVal string var zeroVal uint32
return zeroVal, nil return zeroVal, nil
} }
@ -427,7 +472,7 @@ func (ec *executionContext) field___Type_fields_argsIncludeDeprecated(
// region **************************** field.gotpl ***************************** // region **************************** field.gotpl *****************************
func (ec *executionContext) _Label_id(ctx context.Context, field graphql.CollectedField, obj *model.Label) (ret graphql.Marshaler) { func (ec *executionContext) _Label_id(ctx context.Context, field graphql.CollectedField, obj *graphdto.Label) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Label_id(ctx, field) fc, err := ec.fieldContext_Label_id(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -453,9 +498,9 @@ func (ec *executionContext) _Label_id(ctx context.Context, field graphql.Collect
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(uint32)
fc.Result = res fc.Result = res
return ec.marshalNID2string(ctx, field.Selections, res) return ec.marshalNID2uint32(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_Label_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_Label_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@ -471,7 +516,7 @@ func (ec *executionContext) fieldContext_Label_id(_ context.Context, field graph
return fc, nil return fc, nil
} }
func (ec *executionContext) _Label_name(ctx context.Context, field graphql.CollectedField, obj *model.Label) (ret graphql.Marshaler) { func (ec *executionContext) _Label_name(ctx context.Context, field graphql.CollectedField, obj *graphdto.Label) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Label_name(ctx, field) fc, err := ec.fieldContext_Label_name(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -515,7 +560,7 @@ func (ec *executionContext) fieldContext_Label_name(_ context.Context, field gra
return fc, nil return fc, nil
} }
func (ec *executionContext) _Label_color(ctx context.Context, field graphql.CollectedField, obj *model.Label) (ret graphql.Marshaler) { func (ec *executionContext) _Label_color(ctx context.Context, field graphql.CollectedField, obj *graphdto.Label) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Label_color(ctx, field) fc, err := ec.fieldContext_Label_color(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -559,7 +604,7 @@ func (ec *executionContext) fieldContext_Label_color(_ context.Context, field gr
return fc, nil return fc, nil
} }
func (ec *executionContext) _Post_id(ctx context.Context, field graphql.CollectedField, obj *model.Post) (ret graphql.Marshaler) { func (ec *executionContext) _Post_id(ctx context.Context, field graphql.CollectedField, obj *graphdto.Post) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Post_id(ctx, field) fc, err := ec.fieldContext_Post_id(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -585,9 +630,9 @@ func (ec *executionContext) _Post_id(ctx context.Context, field graphql.Collecte
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(uint32)
fc.Result = res fc.Result = res
return ec.marshalNID2string(ctx, field.Selections, res) return ec.marshalNID2uint32(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_Post_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_Post_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@ -603,7 +648,7 @@ func (ec *executionContext) fieldContext_Post_id(_ context.Context, field graphq
return fc, nil return fc, nil
} }
func (ec *executionContext) _Post_title(ctx context.Context, field graphql.CollectedField, obj *model.Post) (ret graphql.Marshaler) { func (ec *executionContext) _Post_title(ctx context.Context, field graphql.CollectedField, obj *graphdto.Post) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Post_title(ctx, field) fc, err := ec.fieldContext_Post_title(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -647,7 +692,7 @@ func (ec *executionContext) fieldContext_Post_title(_ context.Context, field gra
return fc, nil return fc, nil
} }
func (ec *executionContext) _Post_content(ctx context.Context, field graphql.CollectedField, obj *model.Post) (ret graphql.Marshaler) { func (ec *executionContext) _Post_content(ctx context.Context, field graphql.CollectedField, obj *graphdto.Post) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Post_content(ctx, field) fc, err := ec.fieldContext_Post_content(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -691,7 +736,7 @@ func (ec *executionContext) fieldContext_Post_content(_ context.Context, field g
return fc, nil return fc, nil
} }
func (ec *executionContext) _Post_description(ctx context.Context, field graphql.CollectedField, obj *model.Post) (ret graphql.Marshaler) { func (ec *executionContext) _Post_description(ctx context.Context, field graphql.CollectedField, obj *graphdto.Post) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Post_description(ctx, field) fc, err := ec.fieldContext_Post_description(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -735,7 +780,7 @@ func (ec *executionContext) fieldContext_Post_description(_ context.Context, fie
return fc, nil return fc, nil
} }
func (ec *executionContext) _Post_previewImageUrl(ctx context.Context, field graphql.CollectedField, obj *model.Post) (ret graphql.Marshaler) { func (ec *executionContext) _Post_previewImageUrl(ctx context.Context, field graphql.CollectedField, obj *graphdto.Post) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Post_previewImageUrl(ctx, field) fc, err := ec.fieldContext_Post_previewImageUrl(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -779,7 +824,7 @@ func (ec *executionContext) fieldContext_Post_previewImageUrl(_ context.Context,
return fc, nil return fc, nil
} }
func (ec *executionContext) _Post_labels(ctx context.Context, field graphql.CollectedField, obj *model.Post) (ret graphql.Marshaler) { func (ec *executionContext) _Post_labels(ctx context.Context, field graphql.CollectedField, obj *graphdto.Post) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Post_labels(ctx, field) fc, err := ec.fieldContext_Post_labels(ctx, field)
if err != nil { if err != nil {
return graphql.Null return graphql.Null
@ -805,9 +850,9 @@ func (ec *executionContext) _Post_labels(ctx context.Context, field graphql.Coll
} }
return graphql.Null return graphql.Null
} }
res := resTmp.([]*model.Label) res := resTmp.([]*graphdto.Label)
fc.Result = res fc.Result = res
return ec.marshalNLabel2ᚕᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐLabelᚄ(ctx, field.Selections, res) return ec.marshalNLabel2ᚕᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐLabelᚄ(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_Post_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_Post_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@ -831,6 +876,47 @@ func (ec *executionContext) fieldContext_Post_labels(_ context.Context, field gr
return fc, nil return fc, nil
} }
func (ec *executionContext) _Post_publishedTime(ctx context.Context, field graphql.CollectedField, obj *graphdto.Post) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Post_publishedTime(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.PublishedTime, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalODate2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Post_publishedTime(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Post",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Date does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Query_posts(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Query_posts(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query_posts(ctx, field) fc, err := ec.fieldContext_Query_posts(ctx, field)
if err != nil { if err != nil {
@ -857,9 +943,9 @@ func (ec *executionContext) _Query_posts(ctx context.Context, field graphql.Coll
} }
return graphql.Null return graphql.Null
} }
res := resTmp.([]*model.Post) res := resTmp.([]*graphdto.Post)
fc.Result = res fc.Result = res
return ec.marshalNPost2ᚕᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐPostᚄ(ctx, field.Selections, res) return ec.marshalNPost2ᚕᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐPostᚄ(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_Query_posts(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_Query_posts(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@ -882,6 +968,8 @@ func (ec *executionContext) fieldContext_Query_posts(_ context.Context, field gr
return ec.fieldContext_Post_previewImageUrl(ctx, field) return ec.fieldContext_Post_previewImageUrl(ctx, field)
case "labels": case "labels":
return ec.fieldContext_Post_labels(ctx, field) return ec.fieldContext_Post_labels(ctx, field)
case "publishedTime":
return ec.fieldContext_Post_publishedTime(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type Post", field.Name) return nil, fmt.Errorf("no field named %q was found under type Post", field.Name)
}, },
@ -903,7 +991,7 @@ func (ec *executionContext) _Query_post(ctx context.Context, field graphql.Colle
}() }()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Post(rctx, fc.Args["id"].(string)) return ec.resolvers.Query().Post(rctx, fc.Args["id"].(uint32))
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@ -915,9 +1003,9 @@ func (ec *executionContext) _Query_post(ctx context.Context, field graphql.Colle
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(*model.Post) res := resTmp.(*graphdto.Post)
fc.Result = res fc.Result = res
return ec.marshalNPost2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐPost(ctx, field.Selections, res) return ec.marshalNPost2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐPost(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_Query_post(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_Query_post(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@ -940,6 +1028,8 @@ func (ec *executionContext) fieldContext_Query_post(ctx context.Context, field g
return ec.fieldContext_Post_previewImageUrl(ctx, field) return ec.fieldContext_Post_previewImageUrl(ctx, field)
case "labels": case "labels":
return ec.fieldContext_Post_labels(ctx, field) return ec.fieldContext_Post_labels(ctx, field)
case "publishedTime":
return ec.fieldContext_Post_publishedTime(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type Post", field.Name) return nil, fmt.Errorf("no field named %q was found under type Post", field.Name)
}, },
@ -958,6 +1048,69 @@ func (ec *executionContext) fieldContext_Query_post(ctx context.Context, field g
return fc, nil return fc, nil
} }
func (ec *executionContext) _Query_label(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query_label(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Label(rctx, fc.Args["id"].(uint32))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*graphdto.Label)
fc.Result = res
return ec.marshalNLabel2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐLabel(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Query_label(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "id":
return ec.fieldContext_Label_id(ctx, field)
case "name":
return ec.fieldContext_Label_name(ctx, field)
case "color":
return ec.fieldContext_Label_color(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type Label", field.Name)
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Query_label_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query___type(ctx, field) fc, err := ec.fieldContext_Query___type(ctx, field)
if err != nil { if err != nil {
@ -3050,7 +3203,7 @@ func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field
var labelImplementors = []string{"Label"} var labelImplementors = []string{"Label"}
func (ec *executionContext) _Label(ctx context.Context, sel ast.SelectionSet, obj *model.Label) graphql.Marshaler { func (ec *executionContext) _Label(ctx context.Context, sel ast.SelectionSet, obj *graphdto.Label) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, labelImplementors) fields := graphql.CollectFields(ec.OperationContext, sel, labelImplementors)
out := graphql.NewFieldSet(fields) out := graphql.NewFieldSet(fields)
@ -3099,7 +3252,7 @@ func (ec *executionContext) _Label(ctx context.Context, sel ast.SelectionSet, ob
var postImplementors = []string{"Post"} var postImplementors = []string{"Post"}
func (ec *executionContext) _Post(ctx context.Context, sel ast.SelectionSet, obj *model.Post) graphql.Marshaler { func (ec *executionContext) _Post(ctx context.Context, sel ast.SelectionSet, obj *graphdto.Post) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, postImplementors) fields := graphql.CollectFields(ec.OperationContext, sel, postImplementors)
out := graphql.NewFieldSet(fields) out := graphql.NewFieldSet(fields)
@ -3138,6 +3291,8 @@ func (ec *executionContext) _Post(ctx context.Context, sel ast.SelectionSet, obj
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
out.Invalids++ out.Invalids++
} }
case "publishedTime":
out.Values[i] = ec._Post_publishedTime(ctx, field, obj)
default: default:
panic("unknown field " + strconv.Quote(field.Name)) panic("unknown field " + strconv.Quote(field.Name))
} }
@ -3223,6 +3378,28 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
} }
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
case "label":
field := field
innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_label(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&fs.Invalids, 1)
}
return res
}
rrm := func(ctx context.Context) graphql.Marshaler {
return ec.OperationContext.RootResolverMiddleware(ctx,
func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
case "__type": case "__type":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
@ -3605,13 +3782,13 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se
return res return res
} }
func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) { func (ec *executionContext) unmarshalNID2uint32(ctx context.Context, v any) (uint32, error) {
res, err := graphql.UnmarshalID(v) res, err := graphql.UnmarshalUint32(v)
return res, graphql.ErrorOnPath(ctx, err) return res, graphql.ErrorOnPath(ctx, err)
} }
func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { func (ec *executionContext) marshalNID2uint32(ctx context.Context, sel ast.SelectionSet, v uint32) graphql.Marshaler {
res := graphql.MarshalID(v) res := graphql.MarshalUint32(v)
if res == graphql.Null { if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow") ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@ -3620,7 +3797,11 @@ func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.Selec
return res return res
} }
func (ec *executionContext) marshalNLabel2ᚕᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐLabelᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Label) graphql.Marshaler { func (ec *executionContext) marshalNLabel2gitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐLabel(ctx context.Context, sel ast.SelectionSet, v graphdto.Label) graphql.Marshaler {
return ec._Label(ctx, sel, &v)
}
func (ec *executionContext) marshalNLabel2ᚕᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐLabelᚄ(ctx context.Context, sel ast.SelectionSet, v []*graphdto.Label) graphql.Marshaler {
ret := make(graphql.Array, len(v)) ret := make(graphql.Array, len(v))
var wg sync.WaitGroup var wg sync.WaitGroup
isLen1 := len(v) == 1 isLen1 := len(v) == 1
@ -3644,7 +3825,7 @@ func (ec *executionContext) marshalNLabel2ᚕᚖgitᚗsquidspiritᚗcomᚋsquid
if !isLen1 { if !isLen1 {
defer wg.Done() defer wg.Done()
} }
ret[i] = ec.marshalNLabel2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐLabel(ctx, sel, v[i]) ret[i] = ec.marshalNLabel2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐLabel(ctx, sel, v[i])
} }
if isLen1 { if isLen1 {
f(i) f(i)
@ -3664,7 +3845,7 @@ func (ec *executionContext) marshalNLabel2ᚕᚖgitᚗsquidspiritᚗcomᚋsquid
return ret return ret
} }
func (ec *executionContext) marshalNLabel2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐLabel(ctx context.Context, sel ast.SelectionSet, v *model.Label) graphql.Marshaler { func (ec *executionContext) marshalNLabel2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐLabel(ctx context.Context, sel ast.SelectionSet, v *graphdto.Label) graphql.Marshaler {
if v == nil { if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow") ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@ -3674,11 +3855,11 @@ func (ec *executionContext) marshalNLabel2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋb
return ec._Label(ctx, sel, v) return ec._Label(ctx, sel, v)
} }
func (ec *executionContext) marshalNPost2gitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐPost(ctx context.Context, sel ast.SelectionSet, v model.Post) graphql.Marshaler { func (ec *executionContext) marshalNPost2gitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐPost(ctx context.Context, sel ast.SelectionSet, v graphdto.Post) graphql.Marshaler {
return ec._Post(ctx, sel, &v) return ec._Post(ctx, sel, &v)
} }
func (ec *executionContext) marshalNPost2ᚕᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐPostᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Post) graphql.Marshaler { func (ec *executionContext) marshalNPost2ᚕᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐPostᚄ(ctx context.Context, sel ast.SelectionSet, v []*graphdto.Post) graphql.Marshaler {
ret := make(graphql.Array, len(v)) ret := make(graphql.Array, len(v))
var wg sync.WaitGroup var wg sync.WaitGroup
isLen1 := len(v) == 1 isLen1 := len(v) == 1
@ -3702,7 +3883,7 @@ func (ec *executionContext) marshalNPost2ᚕᚖgitᚗsquidspiritᚗcomᚋsquid
if !isLen1 { if !isLen1 {
defer wg.Done() defer wg.Done()
} }
ret[i] = ec.marshalNPost2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐPost(ctx, sel, v[i]) ret[i] = ec.marshalNPost2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐPost(ctx, sel, v[i])
} }
if isLen1 { if isLen1 {
f(i) f(i)
@ -3722,7 +3903,7 @@ func (ec *executionContext) marshalNPost2ᚕᚖgitᚗsquidspiritᚗcomᚋsquid
return ret return ret
} }
func (ec *executionContext) marshalNPost2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋframeworkᚋgraphᚋmodelᚐPost(ctx context.Context, sel ast.SelectionSet, v *model.Post) graphql.Marshaler { func (ec *executionContext) marshalNPost2ᚖgitᚗsquidspiritᚗcomᚋsquidᚋblogᚗgitᚋbackendᚋinternalᚋadapterᚋcontrollerᚋgraphdtoᚐPost(ctx context.Context, sel ast.SelectionSet, v *graphdto.Post) graphql.Marshaler {
if v == nil { if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow") ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@ -4026,6 +4207,22 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast
return res return res
} }
func (ec *executionContext) unmarshalODate2ᚖstring(ctx context.Context, v any) (*string, error) {
if v == nil {
return nil, nil
}
res, err := graphql.UnmarshalString(v)
return &res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalODate2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler {
if v == nil {
return graphql.Null
}
res := graphql.MarshalString(*v)
return res
}
func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) {
if v == nil { if v == nil {
return nil, nil return nil, nil

View File

@ -1,9 +1,11 @@
package graph package graph
import "git.squidspirit.com/squid/blog.git/backend/internal/application"
// This file will not be regenerated automatically. // This file will not be regenerated automatically.
// //
// It serves as dependency injection for your app, add any dependencies you require here. // It serves as dependency injection for your app, add any dependencies you require here.
type Resolver struct { type Resolver struct {
// db GetAllPostsUseCase application.GetAllPostsUseCase
} }

View File

@ -1,6 +1,4 @@
# GraphQL schema example scalar Date
#
# https://gqlgen.com/getting-started/
type Label { type Label {
id: ID! id: ID!
@ -15,9 +13,11 @@ type Post {
description: String! description: String!
previewImageUrl: String! previewImageUrl: String!
labels: [Label!]! labels: [Label!]!
publishedTime: Date
} }
type Query { type Query {
posts: [Post!]! posts: [Post!]!
post(id: ID!): Post! post(id: ID!): Post!
label(id: ID!): Label!
} }

View File

@ -0,0 +1,38 @@
package graph
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.66
import (
"context"
"fmt"
"git.squidspirit.com/squid/blog.git/backend/internal/adapter/controller"
"git.squidspirit.com/squid/blog.git/backend/internal/adapter/controller/graphdto"
)
// Posts is the resolver for the posts field.
func (r *queryResolver) Posts(ctx context.Context) ([]*graphdto.Post, error) {
c := controller.NewQueryPostsController(r.GetAllPostsUseCase)
dtos, err := c.Handle()
if err != nil {
return nil, err
}
return dtos, nil
}
// Post is the resolver for the post field.
func (r *queryResolver) Post(ctx context.Context, id uint32) (*graphdto.Post, error) {
panic(fmt.Errorf("not implemented: Post - post"))
}
// Label is the resolver for the label field.
func (r *queryResolver) Label(ctx context.Context, id uint32) (*graphdto.Label, error) {
panic(fmt.Errorf("not implemented: Label - label"))
}
// Query returns QueryResolver implementation.
func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }
type queryResolver struct{ *Resolver }

View File

@ -0,0 +1,31 @@
BEGIN;
CREATE TABLE IF NOT EXISTS "post" (
"id" SERIAL PRIMARY KEY,
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"description" TEXT NOT NULL,
"preview_image_url" TEXT NOT NULL,
"published_time" TIMESTAMP,
"created_time" TIMESTAMP NOT NULL,
"updated_time" TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS "label" (
"id" SERIAL PRIMARY KEY,
"name" TEXT NOT NULL,
"color" TEXT NOT NULL,
"created_time" TIMESTAMP NOT NULL,
"updated_time" TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS "post_label" (
"post_id" SERIAL NOT NULL,
"label_id" SERIAL NOT NULL,
"label_order" INTEGER NOT NULL,
PRIMARY KEY ("post_id", "label_id"),
FOREIGN KEY ("post_id") REFERENCES "post" ("id") ON DELETE CASCADE,
FOREIGN KEY ("label_id") REFERENCES "label" ("id") ON DELETE CASCADE
);
COMMIT;

View File

@ -0,0 +1,79 @@
package postgres
import (
"context"
"database/sql"
"encoding/json"
"git.squidspirit.com/squid/blog.git/backend/internal/adapter/gateway"
"git.squidspirit.com/squid/blog.git/backend/internal/adapter/gateway/dbdto"
)
type postDBService struct {
db *sql.DB
}
func NewPostDBService(db *sql.DB) gateway.PostDBService {
return &postDBService{db}
}
func (srv *postDBService) QueryAll() ([]*dbdto.Post, error) {
ctx := context.Background()
rows, err := srv.db.QueryContext(ctx, `
SELECT
p.*,
COALESCE(
jsonb_agg(
jsonb_build_object(
'id', l.id,
'name', l.name,
'color', l.color
) ORDER BY pl.label_order ASC
)
FILTER (WHERE l.id IS NOT NULL),
'[]'::jsonb
) AS labels
FROM post p
LEFT JOIN post_label pl ON p.id = pl.post_id
LEFT JOIN label l ON pl.label_id = l.id
GROUP BY p.id
ORDER BY p.created_time DESC
`)
if err != nil {
return nil, err
}
defer rows.Close()
var labelsJSON []byte
var postDtos []*dbdto.Post
for rows.Next() {
var postDto dbdto.Post
err = rows.Scan(
&postDto.ID,
&postDto.Title,
&postDto.Content,
&postDto.Description,
&postDto.PreviewImageURL,
&postDto.PublishedTime,
&postDto.CreatedTime,
&postDto.UpdatedTime,
&labelsJSON,
)
if err != nil {
return nil, err
}
err := json.Unmarshal(labelsJSON, &postDto.Labels)
if err != nil {
return nil, err
}
postDtos = append(postDtos, &postDto)
}
return postDtos, nil
}

View File

@ -0,0 +1,21 @@
package postgres
import (
"database/sql"
_ "github.com/lib/pq"
)
func Connect(dsn string) (*sql.DB, error) {
db, err := sql.Open("postgres", dsn)
if err != nil {
return nil, err
}
err = db.Ping()
if err != nil {
return nil, err
}
return db, nil
}

View File

@ -1,27 +0,0 @@
package graph
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.66
import (
"context"
"fmt"
model1 "git.squidspirit.com/squid/blog.git/backend/internal/framework/graph/model"
)
// Posts is the resolver for the posts field.
func (r *queryResolver) Posts(ctx context.Context) ([]*model1.Post, error) {
panic(fmt.Errorf("not implemented: Posts - posts"))
}
// Post is the resolver for the post field.
func (r *queryResolver) Post(ctx context.Context, id string) (*model1.Post, error) {
panic(fmt.Errorf("not implemented: Post - post"))
}
// Query returns QueryResolver implementation.
func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }
type queryResolver struct{ *Resolver }

21
backend/internal/pkg/env/env.go vendored Normal file
View File

@ -0,0 +1,21 @@
package env
import (
"os"
)
func GetPort() string {
port, exists := os.LookupEnv("PORT")
if !exists {
return "8000"
}
return port
}
func GetDSN() string {
dsn, exists := os.LookupEnv("DSN")
if !exists {
return "postgres://postgres@127.0.0.1/postgres?sslmode=disable"
}
return dsn
}