Allow "extensions" field in remote schema response

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/2818
GitOrigin-RevId: 505e8bae6d3e11199c229bd2b86af09161eb8b66
This commit is contained in:
David Overton 2021-11-10 13:33:58 +11:00 committed by hasura-bot
parent 984955d194
commit ec60386f9c
4 changed files with 58 additions and 9 deletions

View File

@ -3,6 +3,7 @@
## Next release
(Add highlights/major features below)
- server: log locking DB queries during source catalog migration
- server: fix to allow remote schema response to contain an "extensions" field (#7143)
- console: add comments to tracked functions
### Bug fixes and improvements

View File

@ -545,6 +545,21 @@ coalescePostgresMutations plan = do
_ -> Nothing
Just (oneSourceConfig, mutations)
data GraphQLResponse
= GraphQLResponseErrors [J.Value]
| GraphQLResponseData JO.Value
decodeGraphQLResponse :: LBS.ByteString -> Either Text GraphQLResponse
decodeGraphQLResponse bs = do
val <- mapLeft T.pack $ JO.eitherDecode bs
valObj <- JO.asObject val
case JO.lookup "errors" valObj of
Just (JO.Array errs) -> Right $ GraphQLResponseErrors (toList $ JO.fromOrdered <$> errs)
Just _ -> Left "Invalid \"errors\" field in response from remote"
Nothing -> do
dataVal <- JO.lookup "data" valObj `onNothing` Left "Missing \"data\" field in response from remote"
Right $ GraphQLResponseData dataVal
extractFieldFromResponse ::
forall m.
Monad m =>
@ -557,14 +572,13 @@ extractFieldFromResponse fieldName rsi resultCustomizer resp = do
let namespace = fmap G.unName $ _rscNamespaceFieldName $ rsCustomizer rsi
fieldName' = G.unName $ _rfaAlias fieldName
-- TODO: use RootFieldAlias for remote fields
val <- onLeft (JO.eitherDecode resp) $ do400 . T.pack
valObj <- onLeft (JO.asObject val) do400
dataVal <-
applyResultCustomizer resultCustomizer <$> case JO.toList valObj of
[("data", v)] -> pure v
_ -> case JO.lookup "errors" valObj of
Just (JO.Array err) -> doGQExecError $ toList $ fmap JO.fromOrdered err
_ -> do400 "Received invalid JSON value from remote"
applyResultCustomizer resultCustomizer
<$> do
graphQLResponse <- decodeGraphQLResponse resp `onLeft` do400
case graphQLResponse of
GraphQLResponseErrors errs -> doGQExecError errs
GraphQLResponseData d -> pure d
case namespace of
Just _ ->
-- If using a custom namespace field then the response from the remote server

View File

@ -12,8 +12,8 @@ from graphql import GraphQLError
HGE_URLS=[]
def mkJSONResp(graphql_result):
return Response(HTTPStatus.OK, graphql_result.to_dict(),
def mkJSONResp(graphql_result, extensions={}):
return Response(HTTPStatus.OK, {**graphql_result.to_dict(), **extensions},
{'Content-Type': 'application/json'})
@ -48,6 +48,17 @@ class HelloGraphQL(RequestHandler):
res = hello_schema.execute(request.json['query'])
return mkJSONResp(res)
class HelloGraphQLExtensions(RequestHandler):
def get(self, request):
return Response(HTTPStatus.METHOD_NOT_ALLOWED)
def post(self, request):
if not request.json:
return Response(HTTPStatus.BAD_REQUEST)
res = hello_schema.execute(request.json['query'])
extensions = {'extensions': {'message': 'an extra field in response object'}}
return mkJSONResp(res, extensions)
class User(graphene.ObjectType):
id = graphene.Int()
username = graphene.String()
@ -785,6 +796,7 @@ class MessagesGraphQL(RequestHandler):
handlers = MkHandlers({
'/hello': HelloWorldHandler,
'/hello-graphql': HelloGraphQL,
'/hello-graphql-extensions': HelloGraphQLExtensions,
'/user-graphql': UserGraphQL,
'/country-graphql': CountryGraphQL,
'/character-iface-graphql' : CharacterInterfaceGraphQL,

View File

@ -297,6 +297,28 @@ class TestRemoteSchemaBasic:
st_code, resp = hge_ctx.v1q_f(self.dir + '/basic_bulk_remove_add.yaml')
assert st_code == 200, resp
class TestRemoteSchemaBasicExtensions:
""" basic => no hasura tables are tracked """
teardown = {"type": "clear_metadata", "args": {}}
dir = 'queries/remote_schemas'
@pytest.fixture(autouse=True)
def transact(self, request, hge_ctx):
config = request.config
# This is needed for supporting server upgrade tests
# Some marked tests in this class will be run as server upgrade tests
if not config.getoption('--skip-schema-setup'):
q = mk_add_remote_q('simple 1', 'http://localhost:5000/hello-graphql-extensions')
st_code, resp = hge_ctx.v1q(q)
assert st_code == 200, resp
yield
if request.session.testsfailed > 0 or not config.getoption('--skip-schema-teardown'):
hge_ctx.v1q(self.teardown)
def test_remote_query(self, hge_ctx):
check_query_f(hge_ctx, self.dir + '/basic_query.yaml')
class TestAddRemoteSchemaTbls:
""" tests with adding a table in hasura """