

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Menulis fungsi Lambda untuk Titik Akses S3 Lambda Objek
<a name="olap-writing-lambda"></a>

**catatan**  
Per 7 November 2025, S3 Object Lambda hanya tersedia untuk pelanggan lama yang saat ini menggunakan layanan serta untuk memilih AWS mitra Partner Network (APN). Untuk kemampuan yang mirip dengan S3 Object Lambda, pelajari lebih lanjut di sini - Perubahan ketersediaan [Objek Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazons3-ol-change.html) Lambda.

Bagian ini merinci cara menulis AWS Lambda fungsi untuk digunakan dengan Amazon S3 Object Lambda Access Points.

Untuk mempelajari tentang end-to-end prosedur lengkap untuk beberapa tugas Lambda Objek S3, lihat berikut ini:
+ [Tutorial: Mengubah data untuk aplikasi Anda dengan S3 Object Lambda](tutorial-s3-object-lambda-uppercase.md)
+ [Tutorial: Mendeteksi dan menyunting data PII dengan Objek S3 Lambda dan Amazon Comprehend](tutorial-s3-object-lambda-redact-pii.md)
+ [Tutorial: Menggunakan S3 Lambda Objek untuk menandai gambar secara dinamis saat gambarnya diambil](https://aws.amazon.com/getting-started/hands-on/amazon-s3-object-lambda-to-dynamically-watermark-images/?ref=docs_gateway/amazons3/olap-writing-lambda.html)

**Topics**
+ [Bekerja dengan `GetObject` permintaan di Lambda](#olap-getobject-response)
+ [Bekerja dengan permintaan `HeadObject` di Lambda](#olap-headobject)
+ [Bekerja dengan permintaan `ListObjects` di Lambda](#olap-listobjects)
+ [Bekerja dengan permintaan `ListObjectsV2` di Lambda](#olap-listobjectsv2)
+ [Format konteks peristiwa dan penggunaan](olap-event-context.md)
+ [Bekerja dengan header Range dan partNumber](range-get-olap.md)

## Bekerja dengan `GetObject` permintaan di Lambda
<a name="olap-getobject-response"></a>

Bagian ini mengasumsikan bahwa Titik Akses Lambda Objek Anda dikonfigurasi untuk memanggil fungsi Lambda `GetObject`. S3 Lambda Objek mencakup operasi API Amazon S3, `WriteGetObjectResponse`, yang mengaktifkan fungsi Lambda untuk memberikan data yang disesuaikan dan respons header untuk pemanggil `GetObject`. 

`WriteGetObjectResponse` memberikan Anda kontrol ekstensif atas kode status, header respons, dan badan respons, berdasarkan kebutuhan pemrosesan Anda. Anda dapat menggunakan `WriteGetObjectResponse` untuk menanggapi dengan seluruh objek yang berubah, bagian dari objek yang berubah, atau tanggapan lain berdasarkan konteks aplikasi Anda. Bagian berikut menampilkan contoh-contoh unik penggunaan operasi API `WriteGetObjectResponse`.
+ **Contoh 1:** Menanggapi dengan kode status HTTP 403 (Forbidden) 
+ **Contoh 2:** Merespons dengan citra yang berubah
+ **Contoh 3:** Melakukan streaming konten terkompresi

**Contoh 1: Menanggapi dengan kode status HTTP 403 (Forbidden) **

Anda dapat menggunakan `WriteGetObjectResponse` untuk menanggapi dengan kode status HTTP 403 (Terlarang) berdasarkan isi dari objek.

------
#### [ Java ]



```
package com.amazon.s3.objectlambda;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.WriteGetObjectResponseRequest;

import java.io.ByteArrayInputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example1 {

    public void handleRequest(S3ObjectLambdaEvent event, Context context) throws Exception {
        S3Client s3Client = S3Client.builder().build();

        // Check to see if the request contains all of the necessary information.
        // If it does not, send a 4XX response and a custom error code and message.
        // Otherwise, retrieve the object from S3 and stream it
        // to the client unchanged.
        var tokenIsNotPresent = !event.getUserRequest().getHeaders().containsKey("requiredToken");
        if (tokenIsNotPresent) {
            s3Client.writeGetObjectResponse(WriteGetObjectResponseRequest.builder()
                    .requestRoute(event.outputRoute())
                    .requestToken(event.outputToken())
                    .statusCode(403)
                    .contentLength(0L)
                    .errorCode("MissingRequiredToken")
                    .errorMessage("The required token was not present in the request.")
                    .build(),
                    RequestBody.fromInputStream(new ByteArrayInputStream(new byte[0]), 0L));
            return;
        }

        // Prepare the presigned URL for use and make the request to S3.
        HttpClient httpClient = HttpClient.newBuilder().build();
        var presignedResponse = httpClient.send(
                HttpRequest.newBuilder(new URI(event.inputS3Url())).GET().build(),
                HttpResponse.BodyHandlers.ofInputStream());

        // Stream the original bytes back to the caller.
        s3Client.writeGetObjectResponse(WriteGetObjectResponseRequest.builder()
                .requestRoute(event.outputRoute())
                .requestToken(event.outputToken())
                .build(),
                RequestBody.fromInputStream(presignedResponse.body(),
                    presignedResponse.headers().firstValueAsLong("content-length").orElse(-1L)));
    }
}
```

------
#### [ Python ]



```
import boto3
import requests 

def handler(event, context):
    s3 = boto3.client('s3')

    """
    Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request
    should be delivered and contains a presigned URL in 'inputS3Url' where we can download the requested object from.
    The 'userRequest' object has information related to the user who made this 'GetObject' request to 
    S3 Object Lambda.
    """
    get_context = event["getObjectContext"]
    user_request_headers = event["userRequest"]["headers"]

    route = get_context["outputRoute"]
    token = get_context["outputToken"]
    s3_url = get_context["inputS3Url"]

    # Check for the presence of a 'CustomHeader' header and deny or allow based on that header.
    is_token_present = "SuperSecretToken" in user_request_headers

    if is_token_present:
        # If the user presented our custom 'SuperSecretToken' header, we send the requested object back to the user.
        response = requests.get(s3_url)
        s3.write_get_object_response(RequestRoute=route, RequestToken=token, Body=response.content)
    else:
        # If the token is not present, we send an error back to the user. 
        s3.write_get_object_response(RequestRoute=route, RequestToken=token, StatusCode=403,
        ErrorCode="NoSuperSecretTokenFound", ErrorMessage="The request was not secret enough.")

    # Gracefully exit the Lambda function.
    return { 'status_code': 200 }
```

------
#### [ Node.js ]



```
const { S3 } = require('aws-sdk');
const axios = require('axios').default;

exports.handler = async (event) => {
    const s3 = new S3();

    // Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request
    // should be delivered and contains a presigned URL in 'inputS3Url' where we can download the requested object from.
    // The 'userRequest' object has information related to the user who made this 'GetObject' request to S3 Object Lambda.
    const { userRequest, getObjectContext } = event;
    const { outputRoute, outputToken, inputS3Url } = getObjectContext;

    // Check for the presence of a 'CustomHeader' header and deny or allow based on that header.
    const isTokenPresent = Object
        .keys(userRequest.headers)
        .includes("SuperSecretToken");

    if (!isTokenPresent) {
        // If the token is not present, we send an error back to the user. The 'await' in front of the request
        // indicates that we want to wait for this request to finish sending before moving on. 
        await s3.writeGetObjectResponse({
            RequestRoute: outputRoute,
            RequestToken: outputToken,
            StatusCode: 403,
            ErrorCode: "NoSuperSecretTokenFound",
            ErrorMessage: "The request was not secret enough.",
        }).promise();
    } else {
        // If the user presented our custom 'SuperSecretToken' header, we send the requested object back to the user.
        // Again, note the presence of 'await'.
        const presignedResponse = await axios.get(inputS3Url);
        await s3.writeGetObjectResponse({
            RequestRoute: outputRoute,
            RequestToken: outputToken,
            Body: presignedResponse.data,
        }).promise();
    }

    // Gracefully exit the Lambda function.
    return { statusCode: 200 };
}
```

------

**Contoh 2: Merespons dengan citra yang berubah**

Saat melakukan transformasi citra, Anda mungkin memerlukan semua byte objek sumber sebelum Anda dapat mulai memprosesnya. Dalam kasus ini, permintaan `WriteGetObjectResponse` Anda akan mengembalikan seluruh objek ke aplikasi permintaan dalam satu panggilan.

------
#### [ Java ]



```
package com.amazon.s3.objectlambda;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.WriteGetObjectResponseRequest;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Image;
import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example2V2 {

    private static final int HEIGHT = 250;
    private static final int WIDTH = 250;

    public void handleRequest(S3ObjectLambdaEvent event, Context context) throws Exception {
        S3Client s3Client = S3Client.builder().build();
        HttpClient httpClient = HttpClient.newBuilder().build();

        // Prepare the presigned URL for use and make the request to S3.
        var presignedResponse = httpClient.send(
                HttpRequest.newBuilder(new URI(event.inputS3Url())).GET().build(),
                HttpResponse.BodyHandlers.ofInputStream());

        // The entire image is loaded into memory here so that we can resize it.
        // Once the resizing is completed, we write the bytes into the body
        // of the WriteGetObjectResponse request.
        var originalImage = ImageIO.read(presignedResponse.body());
        var resizingImage = originalImage.getScaledInstance(WIDTH, HEIGHT, Image.SCALE_DEFAULT);
        var resizedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        resizedImage.createGraphics().drawImage(resizingImage, 0, 0, WIDTH, HEIGHT, null);

        var baos = new ByteArrayOutputStream();
        ImageIO.write(resizedImage, "png", baos);

        // Stream the bytes back to the caller.
        s3Client.writeGetObjectResponse(WriteGetObjectResponseRequest.builder()
                .requestRoute(event.outputRoute())
                .requestToken(event.outputToken())
                .build(), RequestBody.fromBytes(baos.toByteArray()));
    }
}
```

------
#### [ Python ]



```
import boto3
import requests 
import io
from PIL import Image

def handler(event, context):
    """
    Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request
    should be delivered and has a presigned URL in 'inputS3Url' where we can download the requested object from.
    The 'userRequest' object has information related to the user who made this 'GetObject' request to 
    S3 Object Lambda.
    """
    get_context = event["getObjectContext"]
    route = get_context["outputRoute"]
    token = get_context["outputToken"]
    s3_url = get_context["inputS3Url"]

    """
    In this case, we're resizing .png images that are stored in S3 and are accessible through the presigned URL
    'inputS3Url'.
    """
    image_request = requests.get(s3_url)
    image = Image.open(io.BytesIO(image_request.content))
    image.thumbnail((256,256), Image.ANTIALIAS)

    transformed = io.BytesIO()
    image.save(transformed, "png")

    # Send the resized image back to the client.
    s3 = boto3.client('s3')
    s3.write_get_object_response(Body=transformed.getvalue(), RequestRoute=route, RequestToken=token)

    # Gracefully exit the Lambda function.
    return { 'status_code': 200 }
```

------
#### [ Node.js ]



```
const { S3 } = require('aws-sdk');
const axios = require('axios').default;
const sharp = require('sharp');

exports.handler = async (event) => {
    const s3 = new S3();

    // Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request
    // should be delivered and has a presigned URL in 'inputS3Url' where we can download the requested object from.
    const { getObjectContext } = event;
    const { outputRoute, outputToken, inputS3Url } = getObjectContext;

    // In this case, we're resizing .png images that are stored in S3 and are accessible through the presigned URL
    // 'inputS3Url'.
    const { data } = await axios.get(inputS3Url, { responseType: 'arraybuffer' });

    // Resize the image.
    const resized = await sharp(data)
        .resize({ width: 256, height: 256 })
        .toBuffer();

    // Send the resized image back to the client.
    await s3.writeGetObjectResponse({
        RequestRoute: outputRoute,
        RequestToken: outputToken,
        Body: resized,
    }).promise();

    // Gracefully exit the Lambda function.
    return { statusCode: 200 };
}
```

------

**Contoh 3: Melakukan streaming konten terkompresi**

Saat Anda mengompresi objek, data terkompresi dihasilkan secara bertahap. Akibatnya, Anda dapat menggunakan permintaan `WriteGetObjectResponse` Anda untuk mengembalikan data terkompresi segera setelah semuanya siap. Seperti yang ditunjukkan dalam contoh ini, Anda tidak perlu mengetahui panjang transformasi yang telah selesai.

------
#### [ Java ]



```
package com.amazon.s3.objectlambda;

import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent;
import com.amazonaws.services.lambda.runtime.Context;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.WriteGetObjectResponseRequest;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example3 {

    public void handleRequest(S3ObjectLambdaEvent event, Context context) throws Exception {
        S3Client s3Client = S3Client.builder().build();
        HttpClient httpClient = HttpClient.newBuilder().build();

        // Request the original object from S3.
        var presignedResponse = httpClient.send(
                HttpRequest.newBuilder(new URI(event.inputS3Url())).GET().build(),
                HttpResponse.BodyHandlers.ofInputStream());

        // Consume the incoming response body from the presigned request,
        // apply our transformation on that data, and emit the transformed bytes
        // into the body of the WriteGetObjectResponse request as soon as they're ready.
        // This example compresses the data from S3, but any processing pertinent
        // to your application can be performed here.
        var bodyStream = new GZIPCompressingInputStream(presignedResponse.body());

        // Stream the bytes back to the caller.
        s3Client.writeGetObjectResponse(WriteGetObjectResponseRequest.builder()
                .requestRoute(event.outputRoute())
                .requestToken(event.outputToken())
                .build(),
                RequestBody.fromInputStream(bodyStream,
                    presignedResponse.headers().firstValueAsLong("content-length").orElse(-1L)));
    }
}
```

------
#### [ Python ]



```
import boto3
import requests
import zlib
from botocore.config import Config


"""
A helper class to work with content iterators. Takes an interator and compresses the bytes that come from it. It
implements 'read' and '__iter__' so that the SDK can stream the response. 
"""
class Compress:
    def __init__(self, content_iter):
        self.content = content_iter
        self.compressed_obj = zlib.compressobj()

    def read(self, _size):
        for data in self.__iter__()
            return data

    def __iter__(self):
        while True:
            data = next(self.content)
            chunk = self.compressed_obj.compress(data)
            if not chunk:
                break

            yield chunk

        yield self.compressed_obj.flush()


def handler(event, context):
    """
    Setting the 'payload_signing_enabled' property to False allows us to send a streamed response back to the client.
    in this scenario, a streamed response means that the bytes are not buffered into memory as we're compressing them,
    but instead are sent straight to the user.
    """
    my_config = Config(
        region_name='eu-west-1',
        signature_version='s3v4',
        s3={
            "payload_signing_enabled": False
        }
    )
    s3 = boto3.client('s3', config=my_config)

    """
    Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request
    should be delivered and has a presigned URL in 'inputS3Url' where we can download the requested object from.
    The 'userRequest' object has information related to the user who made this 'GetObject' request to S3 Object Lambda.
    """
    get_context = event["getObjectContext"]
    route = get_context["outputRoute"]
    token = get_context["outputToken"]
    s3_url = get_context["inputS3Url"]

    # Compress the 'get' request stream.
    with requests.get(s3_url, stream=True) as r:
        compressed = Compress(r.iter_content())

        # Send the stream back to the client.
        s3.write_get_object_response(Body=compressed, RequestRoute=route, RequestToken=token, ContentType="text/plain",
                                     ContentEncoding="gzip")

    # Gracefully exit the Lambda function.
    return {'status_code': 200}
```

------
#### [ Node.js ]



```
const { S3 } = require('aws-sdk');
const axios = require('axios').default;
const zlib = require('zlib');

exports.handler = async (event) => {
    const s3 = new S3();

    // Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request
    // should be delivered and has a presigned URL in 'inputS3Url' where we can download the requested object from.
    const { getObjectContext } = event;
    const { outputRoute, outputToken, inputS3Url } = getObjectContext;

    // Download the object from S3 and process it as a stream, because it might be a huge object and we don't want to
    // buffer it in memory. Note the use of 'await' because we want to wait for 'writeGetObjectResponse' to finish 
    // before we can exit the Lambda function. 
    await axios({
        method: 'GET',
        url: inputS3Url,
        responseType: 'stream',
    }).then(
        // Gzip the stream.
        response => response.data.pipe(zlib.createGzip())
    ).then(
        // Finally send the gzip-ed stream back to the client.
        stream => s3.writeGetObjectResponse({
            RequestRoute: outputRoute,
            RequestToken: outputToken,
            Body: stream,
            ContentType: "text/plain",
            ContentEncoding: "gzip",
        }).promise()
    );

    // Gracefully exit the Lambda function.
    return { statusCode: 200 };
}
```

------

**catatan**  
Meskipun S3 Lambda Objek mengizinkan hingga 60 detik untuk mengirim respons lengkap kepada pemanggil melalui permintaan `WriteGetObjectResponse`, jumlah aktual waktu yang tersedia mungkin kurang. Misalnya, batas waktu fungsi Lambda Anda kemungkinan kurang dari 60 detik. Dalam kasus lain, pemanggil mungkin memiliki batas waktu yang lebih ketat. 

Agar penelepon asli menerima respons selain kode status HTTP 500 (Internal Server Error), panggilan `WriteGetObjectResponse` harus diselesaikan. Jika fungsi Lambda kembali, dengan pengecualian atau sebaliknya, sebelum operasi API `WriteGetObjectResponse` dipanggil, pemanggil asli menerima respons 500 (Internal Server Error). Pengecualian yang diberikan selama waktu yang diperlukan untuk menyelesaikan respons akan mengakibatkan respons terpotong kepada pemanggil. Jika fungsi Lambda menerima respons kode status HTTP 200 (OK) dari panggilan API `WriteGetObjectResponse`, lalu pemanggil asli telah mengirim permintaan lengkap. Respon fungsi Lambda, terlepas dari pengecualian diberikan atau tidak, diabaikan oleh S3 Lambda Objek.

Saat memanggil operasi API `WriteGetObjectResponse`, Amazon S3 membutuhkan rute dan meminta token dari konteks peristiwa. Untuk informasi selengkapnya, lihat [Format konteks peristiwa dan penggunaan](olap-event-context.md).

Parameter rute dan token permintaan diperlukan untuk menghubungkan respons `WriteGetObjectResult` dengan pemanggil asli. Meskipun selalu tepat untuk mencoba kembali respons 500 (Internal Server Error), karena token permintaan adalah token sekali pakai, upaya selanjutnya untuk menggunakannya mungkin menghasilkan respons kode status HTTP 400 (Bad Request). Meskipun panggilan ke `WriteGetObjectResponse` dengan rute dan permintaan token tidak perlu dibuat dari fungsi Lambda yang dipanggil, itu harus dibuat oleh identitas di akun yang sama. Panggilan itu juga harus diselesaikan sebelum fungsi Lambda selesai dieksekusi.

## Bekerja dengan permintaan `HeadObject` di Lambda
<a name="olap-headobject"></a>

Bagian ini mengasumsikan bahwa Titik Akses Lambda Objek Anda telah dikonfigurasi untuk memanggil fungsi Lambda `HeadObject`. Lambda akan menerima payload JSON yang berisi kunci bernama `headObjectContext`. Di dalam konteks, ada properti tunggal yang disebut `inputS3Url`, yang merupakan URL yang telah ditandatangani sebelumnya untuk titik akses pendukung untuk `HeadObject`.

URL yang telah ditandatangani sebelumnya akan menyertakan properti berikut jika ditentukan: 
+ `versionId` (di dalam parameter kueri)
+ `requestPayer` (di dalam header `x-amz-request-payer`)
+ `expectedBucketOwner` (di dalam header `x-amz-expected-bucket-owner`)

Properti lain tidak akan ditandatangani sebelumnya, dan karenanya tidak akan disertakan. Opsi yang tidak ditandatangani yang dikirim sebagai header dapat ditambahkan secara manual ke permintaan saat memanggil URL yang ditandatangani sebelumnya yang ditemukan di header `userRequest`. Opsi enkripsi di sisi server tidak didukung untuk `HeadObject`.

Untuk parameter URI sintaks permintaan, lihat [https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) di *Referensi API Amazon Simple Storage Service*.

Contoh berikut ini menunjukkan muatan input Lambda JSON untuk `HeadObject`.

```
{
  "xAmzRequestId": "requestId",
  "**headObjectContext**": {
    "**inputS3Url**": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=<snip>"
  },
  "configuration": {
       "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap",
       "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap",
       "payload": "{}"
  },
  "userRequest": {
       "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example",
       "headers": {
           "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com",
           "Accept-Encoding": "identity",
           "X-Amz-Content-SHA256": "e3b0c44298fc1example"
       }
   },
   "userIdentity": {
       "type": "AssumedRole",
       "principalId": "principalId",
       "arn": "arn:aws:sts::111122223333:assumed-role/Admin/example",       
       "accountId": "111122223333",
       "accessKeyId": "accessKeyId",
       "sessionContext": {
            "attributes": {
            "mfaAuthenticated": "false",
            "creationDate": "Wed Mar 10 23:41:52 UTC 2021"
       },
       "sessionIssuer": {
            "type": "Role",
            "principalId": "principalId",
            "arn": "arn:aws:iam::111122223333:role/Admin",
            "accountId": "111122223333",
            "userName": "Admin"
            }
       }
    },
  "protocolVersion": "1.00"
}
```

Fungsi Lambda Anda harus mengembalikan objek JSON yang berisi header dan nilai yang akan dikembalikan untuk panggilan `HeadObject`.

Contoh berikut ini menunjukkan struktur respons Lambda JSON untuk `HeadObject`.

```
{
    "statusCode": <number>; // Required
    "errorCode": <string>;
    "errorMessage": <string>;
    "headers": {
        "Accept-Ranges": <string>,
        "x-amz-archive-status": <string>,
        "x-amz-server-side-encryption-bucket-key-enabled": <boolean>,
        "Cache-Control": <string>,
        "Content-Disposition": <string>,
        "Content-Encoding": <string>,
        "Content-Language": <string>,
        "Content-Length": <number>, // Required
        "Content-Type": <string>,
        "x-amz-delete-marker": <boolean>,
        "ETag": <string>,
        "Expires": <string>,
        "x-amz-expiration": <string>,
        "Last-Modified": <string>,
        "x-amz-missing-meta": <number>,
        "x-amz-object-lock-mode": <string>,
        "x-amz-object-lock-legal-hold": <string>,
        "x-amz-object-lock-retain-until-date": <string>,
        "x-amz-mp-parts-count": <number>,
        "x-amz-replication-status": <string>,
        "x-amz-request-charged": <string>,
        "x-amz-restore": <string>,
        "x-amz-server-side-encryption": <string>,
        "x-amz-server-side-encryption-customer-algorithm": <string>,
        "x-amz-server-side-encryption-aws-kms-key-id": <string>,
        "x-amz-server-side-encryption-customer-key-MD5": <string>,
        "x-amz-storage-class": <string>,
        "x-amz-tagging-count": <number>,
        "x-amz-version-id": <string>,
        <x-amz-meta-headers>: <string>, // user-defined metadata 
        "x-amz-meta-meta1": <string>, // example of the user-defined metadata header, it will need the x-amz-meta prefix
        "x-amz-meta-meta2": <string>
        ...
    };
}
```

Contoh berikut menunjukkan cara untuk menggunakan URL yang telah ditentukan sebelumnya untuk mengisi respons Anda dengan mengubah nilai header sesuai kebutuhan sebelum mengembalikan JSON.

------
#### [ Python ]



```
import requests

def lambda_handler(event, context):
    print(event)
    
    # Extract the presigned URL from the input.
    s3_url = event["headObjectContext"]["inputS3Url"]

    # Get the head of the object from S3.     
    response = requests.head(s3_url)
    
    # Return the error to S3 Object Lambda (if applicable).           
    if (response.status_code >= 400):
        return {
            "statusCode": response.status_code,
            "errorCode": "RequestFailure",                         
            "errorMessage": "Request to S3 failed"    
    }
    
    # Store the headers in a dictionary.
    response_headers = dict(response.headers)

    # This obscures Content-Type in a transformation, it is optional to add
    response_headers["Content-Type"] = "" 

    # Return the headers to S3 Object Lambda.     
    return {
        "statusCode": response.status_code,
        "headers": response_headers     
        }
```

------

## Bekerja dengan permintaan `ListObjects` di Lambda
<a name="olap-listobjects"></a>

Bagian ini mengasumsikan bahwa Titik Akses Lambda Objek Anda telah dikonfigurasi untuk memanggil fungsi Lambda `ListObjects`. Lambda akan menerima payload JSON dengan objek baru bernama `listObjectsContext`. `listObjectsContext`berisi properti tunggal, `inputS3Url`, yang merupakan URL yang telah ditandatangani sebelumnya untuk titik akses pendukung untuk `ListObjects`.

Berbeda dengan `GetObject` dan `HeadObject`, URL yang telah ditandatangani sebelumnya akan menyertakan properti berikut jika ditentukan:
+ Semua parameter kueri
+ `requestPayer` (di dalam header `x-amz-request-payer`) 
+ `expectedBucketOwner` (di dalam header `x-amz-expected-bucket-owner`)

Untuk parameter URI sintaks permintaan, lihat [https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) di *Referensi API Amazon Simple Storage Service*.

**penting**  
Kami menyarankan Anda menggunakan versi yang lebih baru, [ListObjectsV2](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html), saat mengembangkan aplikasi. Untuk kompatibilitas mundur, Amazon S3 terus mendukung `ListObjects`.

Contoh berikut ini menunjukkan muatan input Lambda JSON untuk `ListObjects`.

```
{
    "xAmzRequestId": "requestId",
     "**listObjectsContext**": {
     "**inputS3Url**": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/?X-Amz-Security-Token=<snip>",
     },
    "configuration": {
        "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap",
        "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap",
        "payload": "{}"
    },
    "userRequest": {
        "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example",
        "headers": {
            "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com",
            "Accept-Encoding": "identity",
            "X-Amz-Content-SHA256": "e3b0c44298fc1example"
        }
    },
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "principalId",
        "arn": "arn:aws:sts::111122223333:assumed-role/Admin/example",
        "accountId": "111122223333",
        "accessKeyId": "accessKeyId",
        "sessionContext": {
            "attributes": {
                "mfaAuthenticated": "false",
                "creationDate": "Wed Mar 10 23:41:52 UTC 2021"
            },
            "sessionIssuer": {
                "type": "Role",
                "principalId": "principalId",
                "arn": "arn:aws:iam::111122223333:role/Admin",
                "accountId": "111122223333",
                "userName": "Admin"
            }
        }
    },
  "protocolVersion": "1.00"
}
```

Fungsi Lambda Anda harus mengembalikan objek JSON yang berisi kode status, daftar hasil XML, atau informasi kesalahan yang akan dikembalikan dari S3 Lambda Objek.

S3 Lambda Objek tidak memproses atau memvalidasi `listResultXml`, melainkan meneruskannya ke pemanggil `ListObjects`. Untuk `listBucketResult`, S3 Lambda Objek mengharapkan properti tertentu memiliki jenis tertentu dan akan memunculkan pengecualian jika tidak dapat menguraikannya. `listResultXml` dan `listBucketResult` tidak dapat diberikan secara bersamaan.

Contoh berikut menunjukkan cara menggunakan URL yang telah ditandatangani untuk memanggil Amazon S3, dan menggunakan hasilnya untuk mengisi respons, termasuk pemeriksaan kesalahan.

------
#### [ Python ]

```
import requests 
import xmltodict

def lambda_handler(event, context):
    # Extract the presigned URL from the input.
    s3_url = event["listObjectsContext"]["inputS3Url"]


    # Get the head of the object from Amazon S3.
    response = requests.get(s3_url)

    # Return the error to S3 Object Lambda (if applicable).
    if (response.status_code >= 400):
        error = xmltodict.parse(response.content)
        return {
            "statusCode": response.status_code,
            "errorCode": error["Error"]["Code"],
            "errorMessage": error["Error"]["Message"]
        }

    # Store the XML result in a dict.
    response_dict = xmltodict.parse(response.content)

    # This obscures StorageClass in a transformation, it is optional to add
    for item in response_dict['ListBucketResult']['Contents']:
        item['StorageClass'] = ""

    # Convert back to XML.
    listResultXml = xmltodict.unparse(response_dict)
    
    # Create response with listResultXml.
    response_with_list_result_xml = {
        'statusCode': 200,
        'listResultXml': listResultXml
    }

    # Create response with listBucketResult.
    response_dict['ListBucketResult'] = sanitize_response_dict(response_dict['ListBucketResult'])
    response_with_list_bucket_result = {
        'statusCode': 200,
        'listBucketResult': response_dict['ListBucketResult']
    }

    # Return the list to S3 Object Lambda.
    # Can return response_with_list_result_xml or response_with_list_bucket_result
    return response_with_list_result_xml

# Converting the response_dict's key to correct casing
def sanitize_response_dict(response_dict: dict):
    new_response_dict = dict()
    for key, value in response_dict.items():
        new_key = key[0].lower() + key[1:] if key != "ID" else 'id'
        if type(value) == list:
            newlist = []
            for element in value:
                if type(element) == type(dict()):
                    element = sanitize_response_dict(element)
                newlist.append(element)
            value = newlist
        elif type(value) == dict:
            value = sanitize_response_dict(value)
        new_response_dict[new_key] = value
    return new_response_dict
```

------

Contoh berikut ini menunjukkan struktur respons Lambda JSON untuk `ListObjects`.

```
{ 
  "statusCode": <number>; // Required
  "errorCode": <string>;
  "errorMessage": <string>;
  "listResultXml": <string>; // This can also be Error XML string in case S3 returned error response when calling the pre-signed URL

  "listBucketResult": {  // listBucketResult can be provided instead of listResultXml, however they can not both be provided in the JSON response  
        "name": <string>,  // Required for 'listBucketResult'
        "prefix": <string>,  
        "marker": <string>, 
        "nextMarker": <string>, 
        "maxKeys": <int>,   // Required for 'listBucketResult'
        "delimiter": <string>, 
        "encodingType": <string>  
        "isTruncated": <boolean>,  // Required for 'listBucketResult'
        "contents": [  { 
            "key": <string>,  // Required for 'content'
            "lastModified": <string>,  
            "eTag": <string>,  
            "checksumAlgorithm": <string>,   // CRC32,  CRC32C,  SHA1,  SHA256
            "size": <int>,   // Required for 'content'
            "owner": {  
                "displayName": <string>,  // Required for 'owner'
                "id": <string>,  // Required for 'owner'
            },  
            "storageClass": <string>  
            },  
        ...  
        ],  
        "commonPrefixes": [  {  
            "prefix": <string>   // Required for 'commonPrefix'
        },  
        ...  
        ],  
    }
}
```

## Bekerja dengan permintaan `ListObjectsV2` di Lambda
<a name="olap-listobjectsv2"></a>

Bagian ini mengasumsikan bahwa Titik Akses Lambda Objek Anda telah dikonfigurasi untuk memanggil fungsi Lambda `ListObjectsV2`. Lambda akan menerima payload JSON dengan objek baru bernama `listObjectsV2Context`. `listObjectsV2Context`berisi properti tunggal, `inputS3Url`, yang merupakan URL yang telah ditandatangani sebelumnya untuk titik akses pendukung untuk `ListObjectsV2`.

Berbeda dengan `GetObject` dan `HeadObject`, URL yang telah ditandatangani sebelumnya akan menyertakan properti berikut jika ditentukan: 
+ Semua parameter kueri
+ `requestPayer` (di dalam header `x-amz-request-payer`) 
+ `expectedBucketOwner` (di dalam header `x-amz-expected-bucket-owner`)

Untuk parameter URI sintaks permintaan, lihat [https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) di *Referensi API Amazon Simple Storage Service*.

Contoh berikut ini menunjukkan muatan input Lambda JSON untuk `ListObjectsV2`.

```
{
    "xAmzRequestId": "requestId",
     "**listObjectsV2Context**": {
     "**inputS3Url**": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/?list-type=2&X-Amz-Security-Token=<snip>",
     },
    "configuration": {
        "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap",
        "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap",
        "payload": "{}"
    },
    "userRequest": {
        "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example",
        "headers": {
            "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com",
            "Accept-Encoding": "identity",
            "X-Amz-Content-SHA256": "e3b0c44298fc1example"
        }
    },
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "principalId",
        "arn": "arn:aws:sts::111122223333:assumed-role/Admin/example",
        "accountId": "111122223333",
        "accessKeyId": "accessKeyId",
        "sessionContext": {
            "attributes": {
                "mfaAuthenticated": "false",
                "creationDate": "Wed Mar 10 23:41:52 UTC 2021"
            },
            "sessionIssuer": {
                "type": "Role",
                "principalId": "principalId",
                "arn": "arn:aws:iam::111122223333:role/Admin",
                "accountId": "111122223333",
                "userName": "Admin"
            }
        }
    },
  "protocolVersion": "1.00" 
}
```

Fungsi Lambda Anda harus mengembalikan objek JSON yang berisi kode status, daftar hasil XML, atau informasi kesalahan yang akan dikembalikan dari S3 Lambda Objek.

S3 Lambda Objek tidak memproses atau memvalidasi `listResultXml`, melainkan meneruskannya ke pemanggil `ListObjectsV2`. Untuk `listBucketResult`, S3 Lambda Objek mengharapkan properti tertentu memiliki jenis tertentu dan akan memunculkan pengecualian jika tidak dapat menguraikannya. `listResultXml` dan `listBucketResult` tidak dapat diberikan secara bersamaan.

Contoh berikut menunjukkan cara menggunakan URL yang telah ditandatangani untuk memanggil Amazon S3, dan menggunakan hasilnya untuk mengisi respons, termasuk pemeriksaan kesalahan.

------
#### [ Python ]

```
import requests 
import xmltodict

def lambda_handler(event, context):
    # Extract the presigned URL from the input.
    s3_url = event["listObjectsV2Context"]["inputS3Url"]


    # Get the head of the object from Amazon S3.
    response = requests.get(s3_url)

    # Return the error to S3 Object Lambda (if applicable).
    if (response.status_code >= 400):
        error = xmltodict.parse(response.content)
        return {
            "statusCode": response.status_code,
            "errorCode": error["Error"]["Code"],
            "errorMessage": error["Error"]["Message"]
        }

    # Store the XML result in a dict.
    response_dict = xmltodict.parse(response.content)

    # This obscures StorageClass in a transformation, it is optional to add
    for item in response_dict['ListBucketResult']['Contents']:
        item['StorageClass'] = ""

    # Convert back to XML.
    listResultXml = xmltodict.unparse(response_dict)
    
    # Create response with listResultXml.
    response_with_list_result_xml = {
        'statusCode': 200,
        'listResultXml': listResultXml
    }

    # Create response with listBucketResult.
    response_dict['ListBucketResult'] = sanitize_response_dict(response_dict['ListBucketResult'])
    response_with_list_bucket_result = {
        'statusCode': 200,
        'listBucketResult': response_dict['ListBucketResult']
    }

    # Return the list to S3 Object Lambda.
    # Can return response_with_list_result_xml or response_with_list_bucket_result
    return response_with_list_result_xml

# Converting the response_dict's key to correct casing
def sanitize_response_dict(response_dict: dict):
    new_response_dict = dict()
    for key, value in response_dict.items():
        new_key = key[0].lower() + key[1:] if key != "ID" else 'id'
        if type(value) == list:
            newlist = []
            for element in value:
                if type(element) == type(dict()):
                    element = sanitize_response_dict(element)
                newlist.append(element)
            value = newlist
        elif type(value) == dict:
            value = sanitize_response_dict(value)
        new_response_dict[new_key] = value
    return new_response_dict
```

------

Contoh berikut ini menunjukkan struktur respons Lambda JSON untuk `ListObjectsV2`.

```
{  
    "statusCode": <number>; // Required  
    "errorCode": <string>;  
    "errorMessage": <string>;  
    "listResultXml": <string>; // This can also be Error XML string in case S3 returned error response when calling the pre-signed URL  
  
    "listBucketResult": {  // listBucketResult can be provided instead of listResultXml, however they can not both be provided in the JSON response 
        "name": <string>, // Required for 'listBucketResult'  
        "prefix": <string>,  
        "startAfter": <string>,  
        "continuationToken": <string>,  
        "nextContinuationToken": <string>,
        "keyCount": <int>, // Required for 'listBucketResult'  
        "maxKeys": <int>, // Required for 'listBucketResult'  
        "delimiter": <string>,  
        "encodingType": <string>  
        "isTruncated": <boolean>, // Required for 'listBucketResult'  
        "contents": [ {  
            "key": <string>, // Required for 'content'  
            "lastModified": <string>,  
            "eTag": <string>,  
            "checksumAlgorithm": <string>, // CRC32, CRC32C, SHA1, SHA256  
            "size": <int>, // Required for 'content'  
            "owner": {  
                "displayName": <string>, // Required for 'owner'  
                "id": <string>, // Required for 'owner'  
            },  
            "storageClass": <string>  
            },  
            ...  
        ],  
        "commonPrefixes": [ {  
            "prefix": <string> // Required for 'commonPrefix'  
            },  
        ...  
        ],  
    }  
}
```

# Format konteks peristiwa dan penggunaan
<a name="olap-event-context"></a>

**catatan**  
Per 7 November 2025, S3 Object Lambda hanya tersedia untuk pelanggan lama yang saat ini menggunakan layanan serta untuk memilih AWS mitra Partner Network (APN). Untuk kemampuan yang mirip dengan S3 Object Lambda, pelajari lebih lanjut di sini - Perubahan ketersediaan [Objek Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazons3-ol-change.html) Lambda.

Amazon S3 Object Lambda menyediakan konteks tentang permintaan yang sedang dibuat jika diteruskan ke fungsi Anda. AWS Lambda Berikut adalah contoh permintaannya. Deskripsi bidang disertakan setelah contoh.

```
{
    "xAmzRequestId": "requestId",
    "getObjectContext": {
        "inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=<snip>",
        "outputRoute": "io-use1-001",
        "outputToken": "OutputToken"
    },
    "configuration": {
        "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap",
        "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap",
        "payload": "{}"
    },
    "userRequest": {
        "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example",
        "headers": {
            "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com",
            "Accept-Encoding": "identity",
            "X-Amz-Content-SHA256": "e3b0c44298fc1example"
        }
    },
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "principalId",
        "arn": "arn:aws:sts::111122223333:assumed-role/Admin/example",
        "accountId": "111122223333",
        "accessKeyId": "accessKeyId",
        "sessionContext": {
            "attributes": {
                "mfaAuthenticated": "false",
                "creationDate": "Wed Mar 10 23:41:52 UTC 2021"
            },
            "sessionIssuer": {
                "type": "Role",
                "principalId": "principalId",
                "arn": "arn:aws:iam::111122223333:role/Admin",
                "accountId": "111122223333",
                "userName": "Admin"
            }
        }
    },
    "protocolVersion": "1.00"
}
```

Kolom permintaan disertakan dalam permintaan berikut:
+ `xAmzRequestId`–ID permintaan Amazon S3 untuk permintaan ini. Kami merekomendasikan agar Anda mencatat nilai ini untuk membantu dengan debugging.
+ `getObjectContext`–Detail input dan output untuk koneksi ke Amazon S3 dan S3 Lambda Objek.
  + `inputS3Url`–URL yang telah ditandatangani sebelumnya, yang dapat digunakan untuk mengambil objek asli dari Amazon S3. URL ditandatangani dengan menggunakan identitas pemanggil asli, dan izin pengguna tersebut akan berlaku saat URL tersebut digunakan. Jika ada header ditandatangani di URL, fungsi Lambda harus menyertakan header ini dalam panggilan ke Amazon S3, kecuali untuk header `Host`.
  + `outputRoute`–Token perutean yang ditambahkan ke URL S3 Lambda Objek ketika fungsi Lambda memanggil `WriteGetObjectResponse`.
  + `outputToken`–Token buram yang digunakan oleh S3 Lambda Objek untuk mencocokkan panggilan `WriteGetObjectResponse` dengan pemanggil asli.
+ `configuration`–Informasi konfigurasi tentang Titik Akses Lambda Objek.
  + `accessPointArn`–Amazon Resource Name (ARN) dari Titik Akses Lambda Objek yang menerima permintaan ini.
  + `supportingAccessPointArn`–ARN dari titik akses pendukung yang ditentukan dalam konfigurasi Titik Akses Lambda Objek.
  + `payload`–Data kustom yang diterapkan pada konfigurasi Titik Akses Lambda Objek. S3 Lambda Objek memperlakukan data ini sebagai string buram, sehingga mungkin perlu diterjemahkan sebelum digunakan.
+ `userRequest`–Informasi tentang panggilan asli untuk S3 Lambda Objek.
  + `url`–URL permintaan yang didekodekan seperti yang diterima oleh S3 Lambda Objek, tidak termasuk parameter kueri terkait otorisasi.
  + `headers`–Peta string ke string yang berisi header HTTP serta nilai dari panggilan aslinya, tidak termasuk header terkait otorisasi. Jika header yang sama muncul beberapa kali, nilai dari setiap instans header yang sama digabungkan ke dalam daftar yang dibatasi koma. Kasus header asli dipertahankan dalam peta ini.
+ `userIdentity`–Detail tentang identitas yang melakukan panggilan ke S3 Lambda Objek. Untuk informasi lebih lanjut, lihat [Peristiwa Pencatatan Data untuk Pelacakan](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html) dalam *AWS CloudTrail Panduan Pengguna*.
  + `type`–Jenis identitas.
  + `accountId`— Akun AWS yang menjadi milik identitas.
  + `userName`–Nama ramah dari identitas yang melakukan panggilan.
  + `principalId`–Pengidentifikasi unik untuk identitas yang melakukan panggilan.
  + `arn`–ARN pengguna utama yang melakukan panggilan. Bagian terakhir ARN berisi pengguna atau peran yang melakukan panggilan.
  + `sessionContext`–Jika permintaan dibuat dengan kredensial keamanan sementara, elemen ini memberikan informasi tentang sesi yang dibuat untuk kredensial tersebut.
  + `invokedBy`— Nama Layanan AWS yang membuat permintaan, seperti Amazon EC2 Auto AWS Elastic Beanstalk Scaling atau.
  + `sessionIssuer`–Jika permintaan dibuat dengan kredensial keamanan sementara, elemen ini memberikan informasi tentang bagaimana kredensial tersebut diperoleh.
+ `protocolVersion`–ID Versi dari konteks yang disediakan. Format bidang ini adalah `{Major Version}.{Minor Version}`. Nomor versi minor selalu berupa angka dua digit. Penghapusan atau perubahan apa pun pada semantik suatu bidang memerlukan perubahan versi utama dan memerlukan keikutsertaan aktif. Amazon S3 dapat menambahkan kolom baru kapan saja, sehingga Anda mungkin mengalami peningkatan versi kecil. Karena sifat peluncuran perangkat lunak, Anda mungkin melihat beberapa versi minor digunakan sekaligus.

# Bekerja dengan header Range dan partNumber
<a name="range-get-olap"></a>

**catatan**  
Per 7 November 2025, S3 Object Lambda hanya tersedia untuk pelanggan lama yang saat ini menggunakan layanan serta untuk memilih AWS mitra Partner Network (APN). Untuk kemampuan yang mirip dengan S3 Object Lambda, pelajari lebih lanjut di sini - Perubahan ketersediaan [Objek Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazons3-ol-change.html) Lambda.

Saat bekerja dengan objek besar di Lambda Objek Amazon S3, Anda dapat menggunakan header HTTP `Range` untuk mengunduh rentang byte tertentu dari sebuah objek. Untuk mengambil rentang byte berbeda dari dalam objek yang sama, Anda dapat menggunakan koneksi bersamaan ke Amazon S3. Anda juga dapat menentukan parameter `partNumber` (integer antara 1 dan 10.000), yang melakukan permintaan berkisar untuk bagian objek tertentu.

Karena ada beberapa cara yang mungkin Anda inginkan untuk menangani permintaan yang menyertakan parameter `Range` atau `partNumber`, S3 Lambda Objek tidak menerapkan parameter ini ke objek yang ditransformasi. Sebagai gantinya, AWS Lambda fungsi Anda harus mengimplementasikan fungsi ini sesuai kebutuhan untuk aplikasi Anda.

Untuk menggunakan parameter `Range` dan `partNumber` dengan S3 Lambda Objek, Anda melakukan hal berikut ini: 
+ Aktifkan parameter ini di konfigurasi Titik Akses Lambda Objek.
+ Tulis fungsi Lambda yang dapat menangani permintaan yang menyertakan parameter ini.

Langkah-langkah berikut menjelaskan cara untuk mencapai hal ini.

## Langkah 1: Mengonfigurasi Titik Akses Lambda Objek Anda
<a name="range-get-olap-step-1"></a>

Secara default, Titik Akses Objek Lambda merespons dengan kesalahan kode status HTTP 501 (Tidak Diimplementasikan) terhadap permintaan `GetObject` atau `HeadObject` yang berisi parameter `Range` atau `partNumber`, baik di header atau parameter kueri. 

Untuk mengaktifkan Titik Akses Lambda Objek untuk menerima permintaan tersebut, Anda harus menyertakan `GetObject-Range`, `GetObject-PartNumber`, `HeadObject-Range`, atau `HeadObject-PartNumber` dalam bagian `AllowedFeatures` konfigurasi Titik Akses Lambda Objek Anda. Untuk informasi selengkapnya tentang memperbarui konfigurasi Titik Akses Lambda Objek, lihat [Membuat Titik Akses Objek Lambda](olap-create.md). 

## Langkah 2: Menerapkan penanganan `Range` atau `partNumber` di dalam fungsi Lambda Anda
<a name="range-get-olap-step-2"></a>

Saat Titik Akses Lambda Object Anda menginvokasi fungsi Lambda Anda dengan rentang permintaan `GetObject` atau `HeadObject`, parameter `Range` atau `partNumber` disertakan dalam konteks peristiwa. Lokasi parameter dalam konteks peristiwa tergantung pada parameter mana yang digunakan dan bagaimana itu dimasukkan dalam permintaan asli ke Titik Akses Lambda Object, seperti yang dijelaskan dalam tabel berikut. 


| Parameter | Lokasi konteks peristiwa | 
| --- | --- | 
|  `Range` (header)  |  `userRequest.headers.Range`  | 
|  `Range` (parameter kueri)  |  `userRequest.url` (parameter kueri `Range`)  | 
|  `partNumber`  |  `userRequest.url` (parameter kueri `partNumber`)  | 

**penting**  
URL presigned yang disediakan untuk Titik Akses Lambda Objek Anda tidak berisi parameter `Range` atau `partNumber` dari permintaan asli. Lihat opsi berikut tentang cara menangani parameter ini dalam AWS Lambda fungsi Anda.

Setelah Anda mengekstrak nilai `Range` atau `partNumber`, Anda dapat mengambil salah satu pendekatan berikut ini, berdasarkan kebutuhan aplikasi Anda:

1. **Petakan `Range` yang diminta atau `partNumber` ke objek yang diubah (disarankan).** 

   Cara yang paling dapat diandalkan untuk menangani permintaan `Range` atau `partNumber` adalah dengan melakukan hal berikut ini: 
   + Mengambil objek lengkap dari Amazon S3.
   + Mengubah objek tersebut.
   + Terapkan parameter `Range` atau `partNumber` yang diminta ke objek yang diubah.

   Untuk melakukan ini, gunakan URL yang telah ditandatangani sebelumnya untuk mengambil seluruh objek dari Amazon S3, dan kemudian memproses objek tersebut sesuai kebutuhan. Untuk contoh fungsi Lambda yang memproses `Range` parameter dengan cara ini, lihat [sampel ini](https://github.com/aws-samples/amazon-s3-object-lambda-default-configuration/blob/main/function/nodejs_20_x/src/response/range_mapper.ts) di repositori AWS Sampel GitHub .

1. **Petakan `Range` yang diminta ke URL yang telah ditandatangani sebelumnya.**

   Dalam beberapa kasus, fungsi Lambda Anda dapat memetakan permintaan `Range` langsung ke URL yang telah ditentukan sebelumnya untuk mengambil hanya sebagian objek dari Amazon S3. Pendekatan ini hanya sesuai jika transformasi Anda memenuhi kedua kriteria berikut:

   1. Fungsi transformasi Anda dapat diterapkan ke sebagian rentang objek.

   1. Menerapkan parameter `Range` sebelum atau sesudah fungsi transformasi menghasilkan objek yang ditransformasikan yang sama.

   Misalnya, fungsi transformasi yang mengubah semua karakter dalam objek berkode ASCII menjadi huruf besar memenuhi kedua kriteria sebelumnya. Transformasi dapat diterapkan pada bagian dari suatu objek, dan menerapkan parameter `Range` sebelum transformasi mencapai hasil yang sama seperti menerapkannya setelah transformasi.

   Sebaliknya, fungsi yang membalikkan karakter dalam objek yang dikodekan ASCII tidak memenuhi kriteria ini. Fungsi seperti itu memenuhi kriteria 1, karena dapat diterapkan pada rentang objek sebagian. Namun, itu tidak memenuhi kriteria 2, karena menerapkan parameter `Range` sebelum transformasi mencapai hasil yang berbeda daripada menerapkan parameter setelah transformasi. 

   Pertimbangkan permintaan untuk menerapkan fungsi ke tiga karakter pertama dari suatu objek dengan isinya `abcdefg`. Menerapkan parameter `Range` sebelum transformasi hanya mengambil `abc` dan kemudian membalikkan data, mengembalikan `cba`. Tetapi jika parameter diterapkan setelah transformasi, fungsi mengambil seluruh objek, membalikkannya, lalu menerapkan parameter `Range`, mengembalikan `gfe`. Karena hasil ini berbeda, fungsi ini tidak boleh menerapkan parameter `Range` saat mengambil objek dari Amazon S3. Sebaliknya, itu harus mengambil seluruh objek, melakukan transformasi, dan hanya kemudian menerapkan parameter `Range`. 
**Awas**  
Dalam banyak kasus, menerapkan parameter `Range` ke URL yang telah ditandatangani sebelumnya akan menghasilkan perilaku tak terduga oleh fungsi Lambda atau klien yang meminta. Kecuali Anda yakin bahwa aplikasi Anda akan berfungsi dengan baik ketika hanya mengambil sebagian objek dari Amazon S3, kami menyarankan Anda mengambil dan mengubah objek penuh seperti yang dijelaskan sebelumnya dalam pendekatan A. 

   Jika aplikasi Anda memenuhi kriteria yang dijelaskan sebelumnya dalam pendekatan B, Anda dapat menyederhanakan AWS Lambda fungsi Anda dengan mengambil hanya rentang objek yang diminta dan kemudian menjalankan transformasi Anda pada rentang tersebut. 

   Contoh kode Java berikut mendemonstrasikan cara untuk melakukan hal berikut ini: 
   + Ambil header `Range` dari permintaan `GetObject`.
   + Tambahkan header `Range` ke URL yang telah ditandatangani sebelumnya, yang dapat digunakan oleh Lambda untuk mengambil rentang yang diminta dari Amazon S3.

   ```
   private HttpRequest.Builder applyRangeHeader(ObjectLambdaEvent event, HttpRequest.Builder presignedRequest) {
       var header = event.getUserRequest().getHeaders().entrySet().stream()
               .filter(e -> e.getKey().toLowerCase(Locale.ROOT).equals("range"))
               .findFirst();
   
       // Add check in the query string itself.
       header.ifPresent(entry -> presignedRequest.header(entry.getKey(), entry.getValue()));
       return presignedRequest;
   }
   ```