morpheus-graphql icon indicating copy to clipboard operation
morpheus-graphql copied to clipboard

Feature Request: toGlobalDefinitions that passes `TypeDefinition` in the callback

Open pranaysashank opened this issue 3 years ago • 1 comments

Request to add a new function similar to the newly introduced toGlobalDefinitions that is defined as

toGlobalDefinitionsWith :: (TypeDefinition ANY VALID -> Bool) -> Schema VALID -> [ClientTypeDefinition]
toGlobalDefinitionsWith f Schema{types} =
    mapMaybe generateGlobalType $
        filter shouldInclude (toList types)
  where
    shouldInclude t =
        not (isResolverType t)
            && isNotSystemTypeName (typeName t)
            && f t

with this we can filter the generated types based on whether they are Input, Enum, or Scalar and have them in different modules

pranaysashank avatar May 09 '22 12:05 pranaysashank

Hi @pranaysashank, it is internal function. why do you need it?

if you need to filter them by Input, Enum, or Scalar, we should expose new function:

declareGlobalTypesBy ::  FilePath -> [TypeDefinition ANY VALID -> Bool] -> Q[Dec]

feel free to open pull request :)

nalchevanidze avatar Jun 23 '22 23:06 nalchevanidze

@pranaysashank, to follow up, I need an answer if my suggestion would solve your problem.

nalchevanidze avatar Oct 03 '22 10:10 nalchevanidze

@pranaysashank sorry, i think i will close the ticket. if you still want to request feature you can reopen it with more detailed description why we need it.

nalchevanidze avatar Oct 06 '22 18:10 nalchevanidze

Hi, Apologies for the very late reply. Let me explain how we use the morpheus code gen TH facilities in our code base. The compile time for the module with declareGlobalTypes is very large, so we decided to split the modules based on their kinds and for this we filter the type kinds based on whether they are enums, scalar, inputs, or other arbitrary stuff (we further split Input types to separate modules based on a few pattern names). The first idea to do this was to use a function like declareGlobalTypesBy, however the function loads the file from filesystem and parses the whole schema in every module. So this is what we do instead,

  1. In a module called schema, we define
module Schema where

schemaDoc :: GQLResult (Schema VALID)
schemaDoc =
    parseFullSchema $
        Data.ByteString.Lazy.fromStrict
            $(makeRelativeToProject "schema.graphql" >>= embedFile)
            
  1. In a module where we want to define the Global types we then do

module GraphQL.Enum where

handleResult (toGlobalDefinitionsWith isGraphqlEnum <$> schemaDoc) printDeclarations
  1. Similary, for local types we define a function called defQuery
defQuery :: Text -> Q [Dec]
defQuery query = do
    let request =
            GQLRequest
                { query
                , operationName = Nothing
                , variables = Nothing
                }
    handleResult
        ( do
            sd <- schemaDoc
            executableDoc <- Morpheus.parseRequest request
            fst <$> toLocalDefinitions executableDoc sd
        )
        ( printDeclarations
        )

With these changes, we get better compile times

pranaysashank avatar Oct 14 '23 18:10 pranaysashank

Hi, @nalchevanidze did you get a chance to look at my comment. I don't have the permissions to re-open this issue

pranaysashank avatar Dec 16 '23 17:12 pranaysashank