aws / aws-appsync-community

The AWS AppSync community
https://aws.amazon.com/appsync
Apache License 2.0
507 stars 32 forks source link

Add support for content encoding negotiation #15

Open JuanCarlosGonzalez opened 5 years ago

JuanCarlosGonzalez commented 5 years ago

It would be great that AppSync services support content encoding negotiation as API Gateway does. In order to accomplish it, AppSync services should honor Accept-Encoding header a provide compressed responses according to accepted compressions.

We've moved some of our backend services from Api Gateway + AWS Lambda pattern to AWS AppSync and we miss this feature.

Best regards,

Juan Carlos González

vlekakis commented 5 years ago

Hi

Thank you for your interest in AppSync! I will bring your feature request in the team. I'm leaving this issue here open, to see if the rest if the community is interested in this as well.

fgiarritiello commented 5 years ago

Very interested in this feature. Thanks

RogerVin commented 5 years ago

also very interested in this feature

jazztong commented 5 years ago

We recently use AppSync heavily in our service, it will be great if this feature is enabled.

joemastersemison commented 5 years ago

+1, we would love to use gzip

yvele commented 5 years ago

@joemastersemison you can already use gzip with AWS AppSync if you setup CloudFront yourself.

Screenshot 2019-10-16 at 09 48 27

Here is a CloudFormation stack example of how I did it:

  Distribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled : true
        IPV6Enabled : true
        HttpVersion : http
        ...

        # Specific to GraphQL API
        CacheBehaviors:
          - PathPattern: /graphql*
            TargetOriginId: ApiAppSyncGraphQL
            MinTTL: 0
            MaxTTL: 0
            DefaultTTL: 0
            # Automatic gzip
            Compress: true 
            AllowedMethods : [HEAD, DELETE, POST, GET, OPTIONS, PUT, PATCH]
            ViewerProtocolPolicy: https-only
            # Specifies how CloudFront handles query strings or cookies
            ForwardedValues:
              QueryString: true
              Headers:
                # Custom "Authorization" and "Host" should NOT be forwarded!
                - Origin
                - Referer
a-marcel commented 4 years ago

Any news about AppSync support for compression?

markoff-s commented 4 years ago

+1

alexchumak commented 3 years ago

👍

oakstreetrec commented 3 years ago

+1

orcaman commented 3 years ago

+1

mperone commented 3 years ago

@Vlaaaaaaad - why the thumbs down on the last few responses from people? Do you know a better way to do this or is this request misguided in some other way? From my perspective, compression on the AppSync graphql responses would be a big deal.

@yvele - would you mind posting some more details on your cloudformation example? There hasn't been any movement on this in years so I think it may be that your cloudformation example is the best (only?) way to do it. I tried parsing your eaxmple but I'm not sure I 100% understand. And when I tried the serverless-appsync-cloudfront plugin that indicates it would set it up for you, it didn't seem to work.

Vlaaaaaaad commented 3 years ago

@Vlaaaaaaad - why the thumbs down on the last few responses from people? Do you know a better way to do this or is this request misguided in some other way? From my perspective, compression on the AppSync graphql responses would be a big deal.

Because +1 comments don't help at all: they don't push the discussion further and they don't count as votes (reactions on the top comment count, not comments on the issues). The only thing those comments add is spam, hence the thumbs down.

PeteDuncanson commented 3 years ago

Not sure if thumbs up or down really do much on here to be honest.

image

Been going around in circles on this one and still can't get anything working. There are a few cut and paste samples but none I can get working sadly.

mperone commented 3 years ago

I dug into it tonight and got it working. Here's the CloudFormation setup I'm using. I ordered the properties in the same order you'd find them on the console GUI if you were setting it up that way:

Thank you to @yvele, this is essentially his set up with a few added details.

Note 1: The ForwardedValues property is deprecated and it seems that eventually we'll have to change to a CachePolicy and OriginRequestPolicy. I tried a few different setups but unfortunately I couldn't get it to work using those.

Note 2: After you get the CloudFront Distribution up and running, don't forget to change your app to switch to the new endpoint! i.e. fetching from https://something.appsync-api.region.amazonaws.com/graphql -> https://something.cloudfront.net/graphql

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  ### Your description here ###
Resources:
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        HttpVersion: http2
        Origins:
          - Id: AppSyncGraphQLApi
            DomainName: ### Your GraphQL endpoint here (no "https://" prefix and no "/graphql" postfix) ###
            CustomOriginConfig:
              OriginProtocolPolicy: https-only
              HTTPSPort: 443
              OriginSSLProtocols:
                - TLSv1
        DefaultCacheBehavior:
          TargetOriginId: AppSyncGraphQLApi
          Compress: true
          ViewerProtocolPolicy: https-only
          AllowedMethods: [GET, HEAD, OPTIONS, PUT, PATCH, POST, DELETE]
          ForwardedValues:
            Headers:
              - Origin
              - Referer
            QueryString: true
          MinTTL: 0
          MaxTTL: 0
          DefaultTTL: 0
        PriceClass: PriceClass_100
      Tags:
        - Key: Application
          Value: !Ref AWS::StackName
Outputs:
  CloudFrontDistributionDomain:
    Value: !GetAtt CloudFrontDistribution.DomainName
    Export:
      Name: CloudFront-CloudFrontDistributionDomain
PeteDuncanson commented 3 years ago

@mperone thanks for sharing. Can I ask you to explain how you are deploying this? I've been working all day on trying to get my own version of this up and running via Amplify following this https://docs.amplify.aws/cli/usage/customcf#add-custom-aws-resources but getting a nasty error thats blocked me for now.

I'm guessing you are manually deploying this via the console or similar? I've only come to AWS via Amplify so that parts still all a bit new to me. Any pointers would be great to get this up and running and ticked off my list.

Many thanks.

mperone commented 3 years ago

AppSync GraphQL API setup using Serverless

I'm deploying the AppSync GraphQL API using the serverless-appsync-plugin.

CloudFront setup using CloudFormation

I'm deploying the CloudFront Distribution from the command line:

  1. Write yaml cf template and upload to S3:

    aws s3api put-object --bucket <s3 bucket name> --key <relative s3 path>/<new s3 yaml file name> --body <local yaml file path> --storage-class STANDARD_IA

  2. Create Stack:

    aws cloudformation create-stack --stack-name <new stack name> --template-url https://<new s3 yaml file url> --capabilities CAPABILITY_IAM

DilLip-Chowdary-Codes commented 2 years ago

In the Appsync Caching and compression page they mentioned below statement.

Compression is available on all new APIs created after June 1st, 2020.

But still, we're getting the uncompressed response, which takes more time (2x) when compared to traditional API Gateway response with the same request and response payload.

we're using lambda as a data source.

any fix for this? @vlekakis

p0wl commented 1 year ago

@DilLip-Chowdary-Codes it took me a while today to figure out that responses are only compressed if they are above 1kb, as it is pointed out in the Cloudfront documentation: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html (Size of objects that CloudFront compresses: CloudFront compresses objects that are between 1,000 bytes and 10,000,000 bytes in size.).

So if you add the header Accept-Encoding: gzip it works for me with "pure" AppSync (without additional Cloudfront distribution).

70nyIT commented 9 months ago

I'm using Apollo GraphQL client. It automatically adds this header

Accept-Encoding: gzip, deflate, br

The answer doesn't have the Content-Encoding nor it's compressed (and size of the call is 14 kb , so above the min 1kb ).

Does this means that only if exactly gzip is set, the compression is enabled, and it's not able to parse the Accept-Encoding header?

70nyIT commented 9 months ago

Update: what I found super strange is that the first calls within my react app do not have gzip, the following one yes. The picture above is the screenshot of my browser console. All the calls are made by a polling, every 5 seconds. All the calls (event the first ones) have the Accept-Encoding header set the same as the others.

The request and the JSON returned in the response is always exactly the same. As you can see,this first two doesn't have compression (14kb), the others yes.

Can someone explain me what's the logic behind?

image

martin-slater commented 8 months ago

I am seeing similar behavior to @70nyIT . Some requests are being returned compressed and others are not. Disappointingly one that is not is close to 1mb in size is not compressed.

Screenshot 2024-02-15 121223 Screenshot 2024-02-15 121509