我尝试制作一个简单的 GO 服务器,运行 GraphQL 并与 PostgreSQL 连接,文件的编译和执行顺利,与数据库的连接也顺利,但是当我尝试检索数据库中的所有用户时,我总是得到一个EOF,查看我找到的答案
但是答案并不适合我当前的项目。
这是运行的所有文件。
DB.GO
package database
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
const (
host = "localhost"
port = 5432
user = "postgres"
password = "lacb2208"
dbname = "IMOX_Tech_Personal"
)
var database *sql.DB
func init() {
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
var err error
database, err = sql.Open("postgres", psqlInfo)
if err != nil {
log.Fatal(err)
}
}
type User struct {
ID int32 `json:"id"`
UserName string `json:"username"`
}
// UserData is for params
type UserData struct {
UserName string
}
func AllUsers(wrapper func(user *User)) {
res, err := database.Query("SELECT id_user, username FROM public.users")
if err != nil {
log.Println("error fetching all users", err)
}
defer res.Close()
for res.Next() {
user := User{}
if err := res.Scan(&user.ID, &user.UserName); err != nil {
log.Fatal(err)
}
wrapper(&user)
}
}
RESOLVERS.GO
package resolvers
import (
"../database"
)
type Resolver struct{}
type UserResolver struct {
usr *database.User
}
// UserDataResolver is a struct for Resolver of the User params
type UserDataResolver struct {
userData *database.UserData
}
func (r *Resolver) AllUsers() *[]*UserResolver {
var users []*UserResolver
wrapper := func(user *database.User) {
users = append(users, &UserResolver{user})
}
database.AllUsers(wrapper)
return &users
}
func (userR *UserResolver) ID() int32 {
return userR.usr.ID
}
func (userR *UserResolver) UserName() string {
return userR.usr.UserName
}
MAIN.GO
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"./resolvers"
"github.com/graph-gophers/graphql-go"
"github.com/graph-gophers/graphql-go/relay"
)
var (
schema *graphql.Schema
)
const (
schemaGraphQL = "schema.graphqls"
contentTypeKey = "Content-Type"
contentTypeJSONValue = "application/json"
authorizationTokenKey = "AuthorizationToken"
)
type (
Authorization struct {
Status string `json:"status"`
Message string `json:"message"`
AuthorizationToken string `json:"authorization_token`
}
)
func init() {
schemaFile, err := ioutil.ReadFile(schemaGraphQL)
if err != nil {
panic(err)
}
schema = graphql.MustParseSchema(string(schemaFile), &resolvers.Resolver{})
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/", getToken)
router.Handle("/graphiql", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(page)
}))
router.Handle("/query", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next := &relay.Handler{Schema: schema}
// authorization := r.Header.Get(authorizationKey)
// token := strings.Replace(authorization, "Bearer ", "", 1)
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6dHJ1ZSwiaGFzaGVkLXBhc3N3b3JkIjoiZmMzZDBjMDAxMTdmZjFjY2FlOWQzMTAzZTU3M2M5YzMiLCJpc3MiOiJsdWNob25ldHZ2In0.o8D2I3UwZzxDCmdLHQiQ4XLBFcADOiPKgeuq_-32Nmk"
ctx := context.WithValue(r.Context(), authorizationTokenKey, token)
next.ServeHTTP(w, r.WithContext(ctx))
}))
fmt.Println("server is running on port 8989")
server := http.ListenAndServe(":8989", handlers.LoggingHandler(os.Stdout, router))
log.Fatal(server)
}
func getToken(response http.ResponseWriter, request *http.Request) {
response.Header().Set(contentTypeKey, contentTypeJSONValue)
response.WriteHeader(200)
}
var page = []byte(`
<!DOCTYPE html>
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.11.11/graphiql.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.auto.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/graphiql/0.11.11/graphiql.min.js"></script>
</head>
<body style="width: 100%; height: 100%; margin: 0; overflow: hidden;">
<div id="graphiql" style="height: 100vh;">Loading...</div>
<script>
function graphQLFetcher(graphQLParams) {
return fetch("/query", {
method: "post",
body: JSON.stringify(graphQLParams),
credentials: "include",
}).then(function (response) {
return response.text();
}).then(function (responseBody) {
try {
return JSON.parse(responseBody);
} catch (error) {
return responseBody;
}
});
}
ReactDOM.render(
React.createElement(GraphiQL, {fetcher: graphQLFetcher}),
document.getElementById("graphiql")
);
</script>
</body>
</html>
`,
)
和SCHEMA.GRAPHQL
schema {
query: Query
}
type User {
id: Int!
username: String!
}
input UserData {
id: Int!
userName: String!
}
type Query {
allUsers: [User]
}
type Mutation {
addUser(userData: UserData!): User
}
为什么不是数据库中的用户表:
CREATE TABLE public.users
(
id_user integer NOT NULL DEFAULT nextval('users_id_user_seq'::regclass),
username character varying(200) NOT NULL,
password character varying(300) NOT NULL,
hashed_password character varying(300) NOT NULL,
status boolean NOT NULL DEFAULT true,
CONSTRAINT users_pkey PRIMARY KEY (id_user),
CONSTRAINT users_username_key UNIQUE (username)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.users
OWNER TO postgres;
当我运行localhost:8989/query时,我从服务器得到的唯一答案是EOF,但没有从数据库返回用户列表
请任何人都可以告诉我我在我的代码中做错了什么......
或者也许如何做一个好的查询:(
root@Crdzbird-Host:~/GoProjects/go-graphql-sample# curl -XPOST -d '{"query": "{ allUsers{} }"}' localhost:8989/query {"errors":[{"message ":"字段 \"allUsers\" 类型为 \"[User]\" 必须有一个子字段选择。您的意思是 \"allUsers { ... }\"吗?","locations":[{"line" :1,"列":3}]}]}