GraphQL (part 2): Model changes and resolvers (#19486)

This PR adds the necessary resolvers to support
the graphQL front-end. Some additional methods
need to be added to the model structs to support
this. Comments have been made to clarify their purpose.

There is a slight duplication of code in the api layer.
But eventually that's going to go away when we move
away from the REST API entirely.

The schema is in api4/schema.graphqls and gets compiled
into the binary as an asset.

The GraphiQL editor url is at GET /api/v5/graphql.

Everything is behind the feature flag MM_FEATUREFLAGS_GRAPHQL.

```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2022-02-11 12:37:05 +05:30
коммит произвёл GitHub
родитель 88968f9e17
Коммит 3f52bd197a
93 изменённых файлов: 9479 добавлений и 22 удалений

Просмотреть файл

@@ -4,9 +4,12 @@
package api4
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net"
@@ -19,6 +22,7 @@ import (
"time"
"github.com/gorilla/websocket"
graphql "github.com/graph-gophers/graphql-go"
s3 "github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/stretchr/testify/require"
@@ -45,6 +49,7 @@ type TestHelper struct {
Context *request.Context
Client *model.Client4
GraphQLClient *graphQLClient
BasicUser *model.User
BasicUser2 *model.User
TeamAdminUser *model.User
@@ -191,6 +196,7 @@ func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, ent
}
th.Client = th.CreateClient()
th.GraphQLClient = newGraphQLClient(fmt.Sprintf("http://localhost:%v", th.App.Srv().ListenAddr.Port))
th.SystemAdminClient = th.CreateClient()
th.SystemManagerClient = th.CreateClient()
@@ -374,6 +380,13 @@ func (th *TestHelper) TearDown() {
th.ShutdownApp()
}
func closeBody(r *http.Response) {
if r.Body != nil {
_, _ = io.Copy(ioutil.Discard, r.Body)
_ = r.Body.Close()
}
}
var initBasicOnce sync.Once
var userCache struct {
SystemAdminUser *model.User
@@ -768,10 +781,16 @@ func (th *TestHelper) CreateDmChannel(user *model.User) *model.Channel {
func (th *TestHelper) LoginBasic() {
th.LoginBasicWithClient(th.Client)
if os.Getenv("MM_FEATUREFLAGS_GRAPHQL") == "true" {
th.LoginBasicWithGraphQL()
}
}
func (th *TestHelper) LoginBasic2() {
th.LoginBasic2WithClient(th.Client)
if os.Getenv("MM_FEATUREFLAGS_GRAPHQL") == "true" {
th.LoginBasicWithGraphQL()
}
}
func (th *TestHelper) LoginTeamAdmin() {
@@ -793,6 +812,13 @@ func (th *TestHelper) LoginBasicWithClient(client *model.Client4) {
}
}
func (th *TestHelper) LoginBasicWithGraphQL() {
_, _, err := th.GraphQLClient.login(th.BasicUser.Email, th.BasicUser.Password)
if err != nil {
panic(err)
}
}
func (th *TestHelper) LoginBasic2WithClient(client *model.Client4) {
_, _, err := client.Login(th.BasicUser2.Email, th.BasicUser2.Password)
if err != nil {
@@ -1251,3 +1277,22 @@ func (th *TestHelper) SetupScheme(scope string) *model.Scheme {
}
return scheme
}
func (th *TestHelper) MakeGraphQLRequest(input *graphQLInput) (*graphql.Response, error) {
url := fmt.Sprintf("http://localhost:%v", th.App.Srv().ListenAddr.Port) + model.APIURLSuffixV5 + "/graphql"
buf, err := json.Marshal(input)
if err != nil {
panic(err)
}
resp, err := th.GraphQLClient.doAPIRequest("POST", url, bytes.NewReader(buf), map[string]string{})
if err != nil {
panic(err)
}
defer closeBody(resp)
var gqlResp *graphql.Response
err = json.NewDecoder(resp.Body).Decode(&gqlResp)
return gqlResp, err
}