aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 77 forks source link

Javascript VTL support - How to write a custom query for GraphQL and where to store it? #237

Open PeteDuncanson opened 3 years ago

PeteDuncanson commented 3 years ago

I can't seem to find a clean answer on how to create a custom query for my GraphQL schema so that I can re-use it in my clients.

In my case I want to abstract/wrap an existing query with a filter for ease so I don't have to keep remembering what the filter is, its a helper method is all, nothing fancy. Here it is so we have something to focus on/play with:

"""
Returns a collection of Areas that service the passed in postcode (similar to ZipCode for those in the US)
Note: it has to match exactly including case.
"""
query getAreaByPostcode($postcode: String!) {
  listAreas( filter: {
    postcodesCovered: { 
      contains: $postcode
    }
  }) {
    items {
      id
      name
    }
  }
}

Seems there are differing views out there on how to do this but nothing offical that I can find:

I'd love someone to clear up the following queries so I can zero in on this:

I've been trying a number of different guesses at all the above but I can't get my query to appear in my GraphiQL UI at all. Would love to have an up to date definitive answer on this one as my mental model is hazy and incomplete :(

dabit3 commented 3 years ago

Exactly, if you're just writing a custom query, I'd suggest creating a file called something like customQueries.js and putting them there. There is no naming convention, just put them somewhere that will not be overwritten by the CLI.

const getAreaByPostCode = `
  query getAreaByPostcode($postcode: String!) {
    listAreas( filter: {
      postcodesCovered: { 
        contains: $postcode
      }
    }) {
      items {
        id
        name
      }
    }
  }
`

export { getAreaByPostCode }

You can then import them anywhere necessary.

The only queries that the CLI will create for you will be based on the GraphQL directives in your schema.

PeteDuncanson commented 3 years ago

Thank you @dabit :)

This might link up nicely with aws-amplify/amplify-codegen#474 too

PeteDuncanson commented 3 years ago

I thought that custom queries would be picked up automagically if in that folder (./src/graphql) and made available in the schema when using tools like GraphiQL for ease of discovery. Is that understanding wrong? From your answer it sounds like I have to manually pull the queries in separately rather than having them as part of the bigger schema.

UnleashedMind commented 3 years ago

You can add the Type Query as a type extension into your schema definition, and then add the custom resolver for that custom query https://docs.amplify.aws/cli/graphql-transformer/resolvers#custom-resolvers Let us know if that works for your project.

PeteDuncanson commented 3 years ago

@UnleashedMind but that sounds like a new resolver (or a custom one), I'm only wanting to reuse an existing Query, no resolver required. In my initial example above I'm just trying to make a new GraphQL Query that wraps an existing one. That might not be the right way to do it, or even possible but it feels like it should be possible.

My understanding is that I should appear in GraphiQL (or any introspection), its just a convenience wrapper around another existing Query, both of which are GraphQL syntax?

kaustavghosh06 commented 3 years ago

@PeteDuncanson Are you still stuck with this?

PeteDuncanson commented 3 years ago

@kaustavghosh06 well yes and I no. I think I have my answer.

I can't just get a new query added to the schema that I can see without diving into the world of VTL templates. That example in the docs here btw is terrifying and a total put off (https://docs.amplify.aws/cli/graphql-transformer/resolvers#add-a-custom-resolver-that-targets-an-aws-lambda-function) it just screams "go away this is nasty stuff!". I've no idea how to even begin picking all those steps apart to make sense of them. It could be that its all boiler plate and I only need to change a few lines but that is not clear so it screams danger. As a result I won't be doing that and I'll leave that well alone. If that part of the docs could be strengthened it might help, some links to other docs on how to understand the VTL I'm looking at, where to put them and deploy them. As it is it makes a whole lot of assumptions that everything it is describing is just routine day to day stuff...when it really isn't to my brain! :)

As a result I won't be spinning up any custom queries or resolvers anytime soon.

So it looks like what I want to do and what I thought I could do can't be done. Just a reminder I wanted to create a GraphQL query that uses existing GraphQL queries as a convenience/helper and get that injected into my schema so that everything would have it available rather than just having it in my client code. Use case is I have a Lambda that is doing an import that needs this functionality as well as a form on my website that also needs this functionality. To try to keep it DRY and discoverable I wanted it in the schema.

Seems that can't be done but feel free to correct me. If it can't be done then nothing more to do here and you can close this one :(

evanmcd commented 3 years ago

@PeteDuncanson, thanks for writing this up. I've been struggling with the same issue and don't want to go near the steps outlined in the docs.

Is there really not an easier way to get a custom query into the schema and thus available throughout the code base?

PeteDuncanson commented 3 years ago

@evanmcd I here there is a new Javascript way to write these resolvers coming soon. That would at least mean that we could write them in a language we know but any docs for that I would need to assume I know nothing about VTL (or anything for that matter!) and start afresh with "here is what a resolver is, here is what we need to do, why and finally here is the how with samples". Don't know the ETA for this though but I keep hearing of late "soon" which is exciting.

warezWally commented 1 year ago

Is there a related "issue" around this. For the life of me I cannot get it to work, I don't suppose anyone has an example of how a custom query is added to the amplify codegen function?