Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REST API: Add compression to REST API #1390

Merged
merged 4 commits into from
Dec 27, 2022

Conversation

id-ms
Copy link
Contributor

@id-ms id-ms commented Dec 26, 2022

Summary

In order to more easily support returning responses for blocks containing large numbers of transactions, we're adding gzip compression as an available response content encoding.

In order to have a response gzip'd (limited in this PR only to the /v2/block/ endpoint) clients can provide the header:

Accept-Encoding: gzip

For example, in the go-algorand-sdk, you could use the following code to retrieve a compressed block:

client.LookupBlock(rnd).Do(ctx, &common.Header{Key: "Accept-Encoding", Value: "gzip"})

See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding for more details on the Accept-Encoding header.

Test Plan

Added tests for compressed responses from /v2/blocks.

@id-ms id-ms changed the title add gzip middleware based on query param Add gzip to REST API Dec 26, 2022
@codecov
Copy link

codecov bot commented Dec 26, 2022

Codecov Report

Merging #1390 (e071d78) into develop (20982f9) will decrease coverage by 0.01%.
The diff coverage is 100.00%.

@@             Coverage Diff             @@
##           develop    #1390      +/-   ##
===========================================
- Coverage    65.37%   65.36%   -0.02%     
===========================================
  Files           79       79              
  Lines        11279    11283       +4     
===========================================
+ Hits          7374     7375       +1     
- Misses        3340     3342       +2     
- Partials       565      566       +1     
Impacted Files Coverage Δ
api/server.go 63.75% <100.00%> (+1.90%) ⬆️
idb/postgres/postgres.go 64.83% <0.00%> (-0.14%) ⬇️

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@onetechnical onetechnical changed the title Add gzip to REST API REST API: Add gzip to REST API Dec 26, 2022
@id-ms id-ms force-pushed the enable-gzip-in-rest branch from 5a2a7c1 to 2503d34 Compare December 26, 2022 15:58
@id-ms id-ms changed the title REST API: Add gzip to REST API REST API: Add compression to REST API Dec 26, 2022
api/server.go Outdated
Comment on lines 109 to 112
// we currently support compressed result only for GET /v2/blocks/ API
Skipper: func(c echo.Context) bool {
return !strings.Contains(c.Path(), "/v2/blocks/") || c.QueryParam("compress") != "true"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// we currently support compressed result only for GET /v2/blocks/ API
Skipper: func(c echo.Context) bool {
return !strings.Contains(c.Path(), "/v2/blocks/") || c.QueryParam("compress") != "true"
},

The gzip middleware looks like it can write any response in gzip, so while I know the exact issue we're trying to solve is for the blocks endpoint, I don't see a reason not to support it for all APIs.

Also, I think the proper way to request compression from the client side is the Accept-Encoding header. The echo middleware also supports this so it looks like we don't need to do anything further in terms of query params parsing here.

For example, the go-algorand-sdk should be able to get gzip'd output via

client.LookupBlock(rnd).Do(ctx, &common.Header{Key: "Accept-Encoding", Value: "gzip"})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I limited the ability to use gzip just for the /v2/blocks endpoint because I think we need to add tests for all endpoints. In order to avoid that and just address the problem we have, I think it is a good start. If you still think we should support all endpoints I can do that, but adding tests for all endpoints might take a while.

As for your second point, do you suggest we use gzip every time the client support gzip encoding? even if it didn't request it? My approach was only to add the support and not replace it (don't want to break any 3rd party code)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair, let's limit it to the blocks endpoint for now then.

Existing code probably isn't supplying the Accept-Encoding: gzip header. Without specifying the header explicitly, the middleware will won't compress anything, so I expect almost all clients to have the same behavior by default.

api/handlers_e2e_test.go Outdated Show resolved Hide resolved
waitForServer(t, listenAddr)

getBlockFunc := func(t *testing.T, headerOnly bool, useCompression bool) *generated.BlockResponse {
path := "/v2/blocks/1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we make this a parameter, we can generalize this across a bunch of different APIs and test to make sure compression works in general and not just for blocks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're just testing the blocks endpoint for now, we can pull this into a separate function for other APIs later.

Copy link
Contributor

@Eric-Warehime Eric-Warehime left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@id-ms id-ms marked this pull request as ready for review December 27, 2022 18:34
@Eric-Warehime Eric-Warehime changed the base branch from develop to hotfix/2.15.1 December 27, 2022 19:34
@Eric-Warehime Eric-Warehime changed the base branch from hotfix/2.15.1 to develop December 27, 2022 20:31
@Eric-Warehime Eric-Warehime merged commit 34d18c6 into algorand:develop Dec 27, 2022
Eric-Warehime pushed a commit to Eric-Warehime/indexer that referenced this pull request Dec 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants