Skip to content

Instantly share code, notes, and snippets.

@srobertson
Created May 11, 2020 23:48
Show Gist options
  • Save srobertson/4b38b927202cd44975c4dae15fce4b63 to your computer and use it in GitHub Desktop.
Save srobertson/4b38b927202cd44975c4dae15fce4b63 to your computer and use it in GitHub Desktop.
string :: Name -> ResModel o e m
string = ResScalar . Data.Morpheus.Types.String
prompt :: String -> IO Text
prompt msg =
putStr (msg ++ ": ")
>> hFlush stdout -- Send output to terminal now
>> pack <$> getLine -- Get string from User and convert to Text
getSchema :: Monad m => ResponseStream e m Data.Morpheus.Types.Internal.AST.Schema
getSchema =
schemaFromTypeDefinitions
[dsl|
type Query {
deity(name: String): Deity!
}
type Deity {
name: String!
power: [String!]!
}
|]
resolver :: MonadIO m => RootResModel e m
resolver =
RootResModel
{ query =
pure $
ResObject
( ObjectResModel
{ __typename = "Query",
objectFields =
[ ( "deity",
pure
$ ResObject
$ ObjectResModel
{ __typename = "Deity",
objectFields =
[ ( "name",
liftIO $ prompt "Name" >>= pure . string
),
( "power",
pure $
ResList
[string "Shapeshifting"]
)
]
}
)
]
}
),
mutation = pure ResNull,
subscription = pure ResNull
}
main :: IO ()
main = Web.scotty 3000 $ Web.post "/api" $ Web.raw =<< (liftIO . api =<< Web.body)
apiD :: MonadIO m => GQLRequest -> m GQLResponse
apiD req =
renderResponse <$> runResultT app
where
app = do
schema <- getSchema
runApi schema resolver req
api :: L.ByteString -> IO L.ByteString
api = mapAPI apiD
@srobertson
Copy link
Author

srobertson commented May 13, 2020

@nalchevanidze I think I answered my own question when I went to elaborate. Looks like what I was looking for is objectResolvers :: and possibly other Helpers ... that being said. Here's a more detailed account of what I'm trying to do:

Ideally It would be nice to blend things derived by Generics/Morpheus with the swagger gateway I'm creating

I'm building a gateway that blends data from microservices (that expose either Swagger or Graphql endpoints) with some custom logic

Imagine the gateway expose the combined schema below:

type Query {
  deity(name: String!): Deity!
  demigod(name: String!): Demigod
}

"""
Description for Deity
"""
type Deity {
  """
  Description for name
  """
  name: String!
  power: String @deprecated(reason: "some reason for")
}

type Demigod {
  name: String!
  patron: Diety
}

deity() -> Deity comes the above RootResModel done in the example I posted in this gist. Where as demigod() -> Demigod may come from code that looks like the traditional way of working with Morpheus: Something like:

data Demigod = Demigod
  { name :: Text         -- Non-Nullable Field
  , patron    ::  Text   -- Nullable Field
  } deriving (Generic,GQLType)

data DemiGodArgs = DemiGodArgs
  { name      :: Text        -- Required Argument
  } deriving (Generic)

So the question (or task for me to determine) is can I have the best of both worlds.

@nalchevanidze
Copy link

Do you mean like: https://www.apollographql.com/docs/apollo-server/federation/introduction/

Where you can derive resolvers and schema from swagger and merge with api of motpheus?

Yeah. I am considering that too.

morpheusDerivedApi <:> swaggerApi.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment