mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 01:12:56 +03:00
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:
parent
984955d194
commit
ec60386f9c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 """
|
||||
|
Loading…
Reference in New Issue
Block a user