honojs / hono

Web framework built on Web Standards
https://hono.dev
MIT License
16.87k stars 469 forks source link

hono/aws-lambda + @hono/graphql-server GET not working! #2723

Open mthmcalixto opened 1 month ago

mthmcalixto commented 1 month ago

What version of Hono are you using?

4.3.7

What runtime/platform is your app running on?

Lambda

What steps can reproduce the bug?

Any idea why the GET method doesn't work?

import rootResolver from "./resolvers/resolvers"
import { GraphQLFileLoader } from "@graphql-tools/graphql-file-loader"
import { loadSchemaSync } from "@graphql-tools/load"
import { addResolversToSchema } from "@graphql-tools/schema"
import { graphqlServer } from "@hono/graphql-server"
import { serve } from "@hono/node-server"
import { Hono } from "hono"
import { handle } from "hono/aws-lambda"
import { compress } from "hono/compress"
import { cors } from "hono/cors"
import { logger } from "hono/logger"
import { prettyJSON } from "hono/pretty-json"
import path from "path"

const app = new Hono()

app.use(logger())
app.use(cors())
app.use(compress())
app.use(prettyJSON())

const schemaPath = path.join(__dirname, "schemas/schema.graphql")

const schema = loadSchemaSync(schemaPath, {
  loaders: [new GraphQLFileLoader()],
})

const schemaWithResolvers = addResolversToSchema({
  schema,
  resolvers: rootResolver,
})

app.use(
  "/graphql",
  graphqlServer({
    schema: schemaWithResolvers,
  }),
)

if (process.env.AWS_LAMBDA_FUNCTION_NAME) {
  console.log("Running in AWS Lambda environment.")
  exports.handler = handle(app)
} else {
  console.log("Server is running on http://localhost:3000")
  serve(app)
}

What is the expected behavior?

image

What do you see instead?

image

image

Additional information

No response

NamesMT commented 1 month ago

I have noticed (and fixed) this issue a while back when updating my fork to align with hono's current update, you could patch the package for a workaround in the time being. Advertising alert - or you could use my fork: hono-adapter-aws-lambda, it also comes with a triggerProcessor handle AWS trigger events like S3, EventBridge.

I'll proceed to create a PR for official Hono now.

NamesMT commented 1 month ago

Hi @mthmcalixto, coming back to this issue, graphql is using HTTP method and should be supported by the official adapter.

For your case, it is actually because you were including a JSON body with a GET method, which is not supported by the Web Standard Request, you should put it as query parameter for GET requests. And in your test output on AWS Lambda, I guess you were testing with a simple payload like this?: { "hello": true }, This is an invalid request and will throw error.

You could check the AWS doc to see the valid payload for testing.

mthmcalixto commented 1 month ago

@NamesMT Yes, it seems that I passed an empty graphql body and this caused an internal error.

image image

Body empty - Lambda URL: image

Localhost: image

What improvements are there in https://github.com/NamesMT/hono-adapter-aws-lambda?

NamesMT commented 1 month ago

That's weird, is "GraphQL query" in the Body a string that you put in or is it a placeholder by the API Client?, From my testing, when the body is NOT EMPTY for GET requests, Lambda will returns a 502, and the localhost will return a 400 with empty error, that is correct, But if you are sure your body is empty then do the following debug steps:

If after that it still happens, could you setup a repo so that I can clone and test? For my freshly set up repo, the GraphQL works fine with an empty body (400 with message), and will works when I pass it as a query parameter for GET request, example: local: image Lambda: image

Or you know what? You could just screw, never use GET requests and use only POST requests, GraphQL also recommend POST requests for easier sending of the query payload.


For my adapter fork, Currently, it allows unknown events to be processed by v1Processor instead of throwing at isALBEvent check and it adds a triggerProcessor to support custom invokations following the format: { "eventSource": "string" } and AWS event sources like S3, EventBridge,...

mthmcalixto commented 1 month ago

@NamesMT try to put the query empty and do a GET.

image

image

This should return a json error, not an internal error.

image

Here it stops you from continuing, because it returned 502: image

NamesMT commented 1 month ago

Hi @mthmcalixto, this is my response if I put the query empty and do a GET (Lambda): image

The response is a proper 400 with message, not a 502

mthmcalixto commented 1 month ago

Hi @mthmcalixto, this is my response if I put the query empty and do a GET (Lambda): image

The response is a proper 400 with message, not a 502

Try https://httpie.io/docs/desktop

NamesMT commented 1 month ago

@mthmcalixto It will return 400 with message if the body is selected as None, If the body is selected as GraphQL, even with nothing inputted, httpie will still include the JSON body of: {"query": ""}, so this issue is basically user error / HTTP client error.

NamesMT commented 1 month ago

image You could have checked it the whole time in the Request tab 🤦🏽

mthmcalixto commented 1 month ago

image You could have checked it the whole time in the tab 🤦🏽Request

but it shouldn't return a 502 error, but a 400 error

img

NamesMT commented 1 month ago

Hi, The problem here is by web standards, HTTP GET requests cannot contains a Body, and HTTPie will includes a body of {"query": ""} even when you have inputted nothing with GraphQL mode selected, so the request is invalid and therefor will cause error on Lambda while parsing the request.

mthmcalixto commented 1 month ago

Hi, The problem here is by web standards, HTTP GET requests cannot contains a Body, and HTTPie will includes a body of {"query": ""} even when you have inputted nothing with GraphQL mode selected, so the request is invalid and therefor will cause error on Lambda while parsing the request.

That's exactly the error I'm saying, it should return 400, not a 502.

The error is not handled.

zerijodmanguardia commented 2 weeks ago

Having similar issue.

On another note, in just using the Hello World example for AWS lambda in https://hono.dev/getting-started/aws-lambda, this problem can be also replicated. Reverted as of the moment as this issue isn't present at least on v4.2.9 with a couple of drawbacks like this issue ( which was fixed on v4.4.1 ).

NamesMT commented 2 weeks ago

Hi @zerijodmanguardia,

Would greatly appreciate it if you could have the time to create an issue detailing your issue :D

NamesMT commented 2 weeks ago

A TL;DR FYI on the original issue for later comers, the issue was caused by user error, not Hono, more specifically, the HTTP client he is using: "HTTPie" will includes a JSON body with GET request, even when nothing is inputted, this will throw an error on AWS Lambda because it is not allowed according to web standards.