Home  >  Article  >  Backend Development  >  GoLang conditionally serves .js.gz if present, otherwise .js

GoLang conditionally serves .js.gz if present, otherwise .js

WBOY
WBOYforward
2024-02-09 20:36:09328browse

GoLang 有条件地提供 .js.gz(如果存在),否则提供 .js

php editor Apple pointed out when introducing GoLang that GoLang has an interesting and practical feature, that is, when providing JavaScript files, it will conditionally provide .js.gz files ( if exists), otherwise the .js file will be served. This feature can effectively reduce file size, improve web page loading speed, and give users a better experience. This intelligent file selection mechanism makes GoLang more efficient and flexible in web development. Whether it is front-end or back-end development, GoLang is an excellent programming language worth exploring.

Question content

My background is mostly in react/frontend, but I've been tasked with improving the performance of our React web application, which is served using GoLang, using Go's aws sdk extracts files from S3. I've configured Webpack to do its job and use as many of its optimization features as possible, including using its compression plugin to create gzip-compressed .js.gz files along with the .js files in the bundle deployed to S3.

My question is, is there a way in Go and aws sdk that when it gets a file from an s3 bucket, first determines if a gzip compressed form of the file exists and then gets the file if it doesn't exist Regular document? Is this the best way to solve this problem? I know there is a library for runtime compression in Go, but it seems more efficient to do the compression ahead of time.

The Go server part is very small and has a function to get the bucket file which basically creates an s3 client and then uses the getObject method on that client to get the contents of the bucket and then uses http's .write Method.ResponseWriter contains the body of these contents.

Solution

Yes, you can send the compressed version directly.

This is an example:

package main

import (
    "fmt"
    "net/http"
    "strings"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func getFileFromS3(bucket, key string, w http.ResponseWriter, r *http.Request) error {
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("your-region"),
        // Add other necessary configurations
    })
    if err != nil {
        return err
    }

    client := s3.New(sess)

    // Check if gzipped version exists
    gzKey := key + ".gz"
    _, err = client.HeadObject(&s3.HeadObjectInput{
        Bucket: aws.String(bucket),
        Key:    aws.String(gzKey),
    })
    if err == nil {
        // Gzipped version exists, fetch and serve directly
        obj, err := client.GetObject(&s3.GetObjectInput{
            Bucket: aws.String(bucket),
            Key:    aws.String(gzKey),
        })
        if err != nil {
            return err
        }
        defer obj.Body.Close()

        // Set appropriate headers
        w.Header().Set("Content-Encoding", "gzip")
        w.Header().Set("Content-Type", "application/javascript") // Set the appropriate content type

        // Copy the gzipped content directly to the response
        _, err = fmt.Fprint(w, obj.Body)
        return err
    }

    // Gzipped version doesn't exist, fetch the regular version
    obj, err := client.GetObject(&s3.GetObjectInput{
        Bucket: aws.String(bucket),
        Key:    aws.String(key),
    })
    if err != nil {
        return err
    }
    defer obj.Body.Close()

    // Set appropriate headers
    w.Header().Set("Content-Type", "application/javascript") // Set the appropriate content type

    // Copy the regular content directly to the response
    _, err = fmt.Fprint(w, obj.Body)
    return err
}

func handler(w http.ResponseWriter, r *http.Request) {
    // Extract the file key from the request URL or any other way you have it
    fileKey := "your-file-key"

    // Set appropriate cache headers, handle CORS, etc.

    // Fetch the file from S3
    err := getFileFromS3("your-s3-bucket", fileKey, w, r)
    if err != nil {
        // Handle error, e.g., return a 404 or 500 response
        http.Error(w, "Internal Server Error", http.StatusInternalServerError)
        return
    }
}

func main() {
    http.HandleFunc("/your-endpoint", handler)
    http.ListenAndServe(":8080", nil)
}

The above is the detailed content of GoLang conditionally serves .js.gz if present, otherwise .js. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete