Cách chuyển một chuỗi truy vấn hoặc tham số tuyến đến AWS Lambda từ Amazon API Gateway


348

ví dụ nếu chúng ta muốn sử dụng

GET /user?name=bob

hoặc là

GET /user/bob

Làm thế nào bạn sẽ vượt qua cả hai ví dụ này như là một tham số cho hàm Lambda?

Tôi đã thấy điều gì đó về việc đặt "ánh xạ từ" trong tài liệu, nhưng tôi không thể tìm thấy cài đặt đó trong bảng điều khiển API Gateway.

  • method.request.path.parameter-namecho một tham số đường dẫn có tên parameter-namenhư được xác định trong trang Yêu cầu phương thức.
  • method.request.querystring.parameter-namecho một tham số chuỗi truy vấn có tên parameter-namenhư được xác định trong trang Yêu cầu phương thức.

Tôi không thấy một trong các tùy chọn này mặc dù tôi đã xác định chuỗi truy vấn.

Câu trả lời:


299

Kể từ tháng 9 năm 2017, bạn không còn phải định cấu hình ánh xạ để truy cập vào thân yêu cầu.

Tất cả những gì bạn cần làm là kiểm tra "Sử dụng tích hợp Lambda Proxy", trong Yêu cầu tích hợp, trong tài nguyên.

nhập mô tả hình ảnh ở đây

Sau đó, bạn sẽ có thể truy cập các tham số truy vấn, tham số đường dẫn và tiêu đề như vậy

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']

23
Đây là một mẹo tuyệt vời. Nhưng, hãy nhớ rằng việc bật Lambda Proxy Integration có thể gây ra lỗi "Phản hồi Proxy Lambda không đúng định dạng". Dưới đây là cách khắc phục: stackoverflow.com/questions/43708017/ từ
AaronBaker

5
Có cách nào để làm điều này trong java, trong khi vẫn giữ quá trình giải tuần tự minh bạch mà việc triển khai RequestHandlercung cấp không?
giày

2
thiết lập này ở đâu?
red888

2
@MattWestlake Bạn tạo một tài nguyên được gọi là người dùng và dưới đó là tài nguyên có tên {name} trong API Gateway.
Jonathan

3
Tôi chỉ muốn đề cập rằng sau thay đổi này, tôi cũng phải truy cập Amazon API Gateway -> Hành động -> Triển khai API và triển khai lại vào môi trường trực tiếp.
victorvartan

221

Các bước để làm việc này là:

Trong Bảng điều khiển API Gateway ...

  1. đi đến Resources -> Integration Request
  2. nhấp vào biểu tượng dấu cộng hoặc chỉnh sửa bên cạnh thả xuống mẫu (lẻ tôi biết vì trường mẫu đã mở và nút ở đây có vẻ hơi mờ)
  3. Nhập hoàn toàn application/jsonvào trường loại nội dung mặc dù nó hiển thị mặc định (nếu bạn không làm điều này, nó sẽ không lưu và sẽ không cung cấp cho bạn một thông báo lỗi)
  4. đặt cái này vào ánh xạ đầu vào { "name": "$input.params('name')" }

  5. nhấp vào hộp kiểm bên cạnh danh sách thả xuống mẫu (Tôi giả sử đây là thứ cuối cùng lưu nó)


9
Bạn đã bao giờ nhận được điều này để gửi qua các tham số URL trong các URL như / user / bob trong đó tuyến đường là / user / {username} chưa? Tôi đã thử tất cả các loại hoán vị, nhưng không thể làm được điều đó.
Lucas

5
Có ai biết nếu có bất kỳ tài liệu chính thức? sẽ thật tuyệt khi chỉ cần vượt qua tất cả các tham số truy vấn hoặc xử lý các giá trị tùy chọn một cách duyên dáng hơn các chuỗi trống
AxelTheGerman

6
Một mẹo dành cho nhà phát triển iOS: API Gateway sẽ không chuyển dữ liệu truy vấn cho đến khi bạn xác định từng biến là chuỗi truy vấn (trong 'Yêu cầu phương thức') VÀ triển khai API. Cho đến khi triển khai, nó hoạt động từ kiểm tra bảng điều khiển, nhưng cắt từ các truy vấn của ứng dụng.
AlexeyVMP


6
Lucas, tôi đã làm cho nó hoạt động bằng cách sử dụng mẫu / user / {username}. Chỉ cần nhớ nếu đường dẫn tài nguyên GET của bạn là / user / {username}, trong bước 4, ánh xạ đầu vào trông giống như {"name": "$ input.params ('username')"}
Gerard

134

Tôi đã sử dụng mẫu ánh xạ này để cung cấp Tham số chuỗi truy vấn cơ thể, tiêu đề, phương thức, đường dẫn và URL cho sự kiện Lambda. Tôi đã viết một bài đăng trên blog giải thích mẫu chi tiết hơn: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api- cổng /

Đây là Mẫu bản đồ bạn có thể sử dụng:

{
  "method": "$context.httpMethod",
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "queryParams": {
    #foreach($param in $input.params().querystring.keySet())
    "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "pathParams": {
    #foreach($param in $input.params().path.keySet())
    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end

    #end
  }  
}

Kinh ngạc! Tôi đã vật lộn với việc chuyển mọi thứ theo cách rộng rãi cho người xử lý của tôi. Câu trả lời tốt nhất ở đây.
Venkat D.

Tôi đã làm điều này, nhưng tôi chưa nhận được bất cứ điều gì. Nó hiển thị Không xác định. Chúng tôi phải gửi Thông số trong URL như thế nào? và chúng ta có cần chỉ định tên biến trong url như trong kịch bản url GET bình thường không? Xin hãy giúp tôi ra với điều này.
Parthapratim Neog

8
Không bao giờ tôi có kết quả. Vấn đề là, tôi đã thêm ánh xạ và chỉ lưu nó, và không phải deploylà api một lần nữa. Khi tôi triển khai api với ánh xạ mới, nó hoạt động tốt. Cảm ơn rất nhiều.
Parthapratim Neog

@ shashu10 Xem câu trả lời của tôi
matsev

1
Tôi không thể bắt đầu cho bạn biết blog của bạn hữu ích như thế nào. Trước tiên tôi đã tìm thấy bài đăng "eturn-html-from-aws-api-gateway" và theo dõi nó, bởi vì đó chính xác là những gì tôi cần. Bây giờ tôi cần truyền một số tham số vào hàm và sửa đổi html dựa trên đó - và một lần nữa bạn là người duy nhất có hướng dẫn thực sự! Tất cả các hướng dẫn khác mà tôi tìm thấy dường như bỏ lỡ điểm.
dùng3685427

41

Ngày nay, mẫu thả xuống được bao gồm trong Bảng điều khiển API Gateway trên AWS.

Đối với API của bạn, nhấp vào tên tài nguyên ... sau đó NHẬN

Mở rộng "Mẫu bản đồ cơ thể"

Gõ vào

ứng dụng / json

cho Kiểu nội dung (phải được gõ rõ ràng) và nhấp vào đánh dấu

Một cửa sổ mới sẽ mở ra với dòng chữ "Tạo mẫu" và thả xuống (xem hình ảnh).

Lựa chọn

Phương thức Yêu cầu thông qua

nhập mô tả hình ảnh ở đây

Sau đó bấm lưu

Để truy cập bất kỳ biến nào, chỉ cần sử dụng cú pháp sau (đây là Python), vd: URL:

https://yourURL.execute-api.us-west-2.amazonaws.com/prod/confirmReg?token=12345&uid=5

Bạn có thể nhận được các biến như sau:

from __future__ import print_function

import boto3
import json

print('Loading function')


def lambda_handler(event, context):
    print(event['params']['querystring']['token'])
    print(event['params']['querystring']['uid'])

Vì vậy, không cần phải đặt tên rõ ràng hoặc ánh xạ từng biến bạn muốn.


thông minh! các chức năng có ngay trong dịch vụ nhưng đã bỏ lỡ nó!
hnvasa

25

Để truyền tham số cho hàm lambda của bạn, bạn cần tạo ánh xạ giữa yêu cầu API Gateway và hàm lambda của bạn. Ánh xạ được thực hiện trong phần Integration Request-> Mapping templatescủa tài nguyên API Gateway đã chọn.

Tạo một bản đồ loại application/json, sau đó ở bên phải bạn sẽ chỉnh sửa (nhấp vào bút chì) mẫu.

Mẫu ánh xạ thực sự là một mẫu Vận tốc trong đó bạn có thể sử dụng if, vòng lặp và tất nhiên là in các biến trên đó. Mẫu có các biến này được chèn vào nơi bạn có thể truy cập các tham số chuỗi truy vấn, tiêu đề yêu cầu, v.v. Với đoạn mã sau, bạn có thể tạo lại toàn bộ chuỗi truy vấn:

{
    "querystring" : "#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0)&#end$util.urlEncode($key)=$util.urlEncode($input.params().querystring.get($key))#end",
    "body" : $input.json('$')
}

Lưu ý: nhấp vào biểu tượng kiểm tra để lưu mẫu. Bạn có thể kiểm tra các thay đổi của mình bằng nút "kiểm tra" trong tài nguyên của mình. Nhưng để kiểm tra các tham số chuỗi truy vấn trong bảng điều khiển AWS, bạn sẽ cần xác định tên tham số trong Method Requestphần tài nguyên của mình.

Lưu ý: kiểm tra Hướng dẫn sử dụng Velocity để biết thêm thông tin về ngôn ngữ tạo khuôn mẫu Vận tốc.

Sau đó, trong mẫu lambda của bạn, bạn có thể làm như sau để có được chuỗi truy vấn được phân tích cú pháp:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo

9
Đây là giải pháp tốt nhất. Hãy nhớ làm điều Actions>Deploy APIđó sau đó (Tôi đã lãng phí thời gian của mình để quên điều này ...). Lambda arn liên quan sẽ thực hiện thay đổi ngay sau khi triển khai. Bạn có thể kiểm tra nó trong Stages > #stage (like: prod) > Deployment History.
loretoparisi

24

Câu trả lời được chấp nhận hoạt động tốt với tôi, nhưng mở rộng dựa trên câu trả lời của gimenete, tôi muốn có một mẫu chung mà tôi có thể sử dụng để vượt qua tất cả các tham số truy vấn / đường dẫn / tiêu đề (giống như các chuỗi bây giờ) và tôi đã đưa ra mẫu sau. Tôi đang đăng nó ở đây trong trường hợp ai đó thấy nó hữu ích:

#set($keys = [])
#foreach($key in $input.params().querystring.keySet())
  #set($success = $keys.add($key))
#end

#foreach($key in $input.params().headers.keySet())
  #if(!$keys.contains($key))
    #set($success = $keys.add($key))
  #end
#end

#foreach($key in $input.params().path.keySet())
  #if(!$keys.contains($key))
    #set($success = $keys.add($key))
  #end
#end

{
#foreach($key in $keys)
  "$key": "$util.escapeJavaScript($input.params($key))"#if($foreach.hasNext),#end
#end
}

1
Fab, tôi muốn có thể sử dụng cùng một hàm cho cả các yêu cầu POST (với thân JSON) và GET với các chuỗi truy vấn. Làm việc một giấc mơ. Cảm ơn!
Matt Fletcher

@benv đây có phải là mẫu đầy đủ không?
nxmohamad

17

Là một phần của việc cố gắng trả lời một trong những câu hỏi của riêng tôi ở đây , tôi đã tìm ra mẹo này.

Trong mẫu ánh xạ Cổng API, sử dụng thông tin sau để cung cấp cho bạn chuỗi truy vấn hoàn chỉnh như được gửi bởi ứng dụng khách HTTP:

{
    "querystring": "$input.params().querystring"
}

Ưu điểm là bạn không phải giới hạn bản thân trong một tập hợp các khóa được ánh xạ được xác định trước trong chuỗi truy vấn của bạn. Bây giờ bạn có thể chấp nhận bất kỳ cặp khóa-giá trị nào trong chuỗi truy vấn, nếu đây là cách bạn muốn xử lý.

Lưu ý: Theo đó , chỉ $input.params(x)được liệt kê dưới dạng một biến có sẵn cho mẫu VTL. Có thể là nội bộ có thể thay đổi và querystringcó thể không còn có sẵn.


1
Điều này vẫn hoạt động kể từ tháng 5 năm 2017 nhưng nó trả về đối tượng JS mà API Gateway tạo cho bạn thay vì chuỗi truy vấn thực tế. Điều này gây khó chịu cho tôi vì tôi đang cố phân tích chuỗi truy vấn để biến các thông số lặp lại thành một mảng.
Tom Saleeba

11

Bây giờ bạn sẽ có thể sử dụng loại tích hợp proxy mới cho Lambda để tự động nhận yêu cầu đầy đủ trong hình dạng tiêu chuẩn, thay vì định cấu hình ánh xạ.

xem: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on- tài nguyên proxy


1
Tôi không chắc tại sao, nhưng tích hợp proxy thường không hoạt động với tôi. Tôi đã phải xóa nó khỏi các API mới nhất mà tôi đã tạo.
Gustavo Straube

tương tự ^ hơn nữa tôi đã gặp sự cố CORS với API Gateway. Theo cùng với các tài liệu AWS, tôi không thể làm cho CORS hoạt động. Tuy nhiên, tôi đã tìm thấy một bài viết Medium cũ từ giữa cuối năm 2015 với cách thiết lập CORS thủ công và nó đã hoạt động.
Stephen Tetreault

7

NHẬN / người dùng? Tên = bob

{
    "name": "$input.params().querystring.get('name')"
}

NHẬN / người dùng / bob

{
    "name": "$input.params('name')"
}

5

Rất nhiều câu trả lời ở đây là tuyệt vời. Nhưng tôi muốn một cái gì đó đơn giản hơn một chút. Tôi muốn một cái gì đó sẽ hoạt động với mẫu "Hello World" miễn phí. Điều này có nghĩa là tôi muốn một đơn giản tạo ra một thân yêu cầu khớp với chuỗi truy vấn:

{
#foreach($param in $input.params().querystring.keySet())
  "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
}

Tôi nghĩ rằng câu trả lời hàng đầu tạo ra một cái gì đó hữu ích hơn khi xây dựng một cái gì đó thực sự, nhưng để có được một thế giới xin chào nhanh chóng chạy bằng cách sử dụng mẫu từ AWS, điều này hoạt động rất tốt.


4

Ví dụ ánh xạ tham số sau đây chuyển tất cả các tham số, bao gồm đường dẫn, chuỗi truy vấn và tiêu đề, đến điểm cuối tích hợp thông qua tải trọng JSON

#set($allParams = $input.params())
{
  "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
      #foreach($paramName in $params.keySet())
      "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
      #if($foreach.hasNext),#end
      #end
    }
    #if($foreach.hasNext),#end
    #end
  }
}

Trong thực tế, mẫu ánh xạ này xuất ra tất cả các tham số yêu cầu trong tải trọng như được nêu như sau:

{
  "parameters" : {
     "path" : {    
       "path_name" : "path_value", 
       ...
     }
     "header" : {  
       "header_name" : "header_value",
       ...
     }
     'querystring" : {
       "querystring_name" : "querystring_value",
       ...
     }
   }
}

Sao chép từ Hướng dẫn dành cho nhà phát triển Amazon API Gateway


2

Chuỗi truy vấn được chuyển thẳng sang phân tích cú pháp trong javascript trong lambda

cho GET / người dùng? name = bob

 var name = event.params.querystring.name;

Điều này không giải quyết được câu hỏi GET user / bob.


sự kiện của nó.queryStringParameter.name
Neo

Tôi phải làmevent.queryStringParameters.name
Anders Kitson

2

Như câu trả lời của @ Jonathan, sau khi đánh dấu Sử dụng tích hợp Lambda Proxy trong Yêu cầu tích hợp , trong mã nguồn của bạn, bạn nên triển khai theo định dạng dưới đây để vượt qua lỗi 502 Cổng xấu .

Nút Node 8.1:

exports.handler = async (event, context, callback) => {
  // TODO: You could get path, parameter, headers, body value from this
  const { path, queryStringParameters, headers, body } = event;

  const response = {
    "statusCode": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "body": JSON.stringify({
      path, 
      query: queryStringParameters,
      headers,
      body: JSON.parse(body)
    }),
    "isBase64Encoded": false
  };

  return response;
};

Đừng quên triển khai tài nguyên của bạn tại API Gateway trước khi chạy lại API của bạn. Phản hồi JSON chỉ trả về bộ nào trong thân là chính xác. Vì vậy, bạn có thể nhận được đường dẫn, tham số, tiêu đề, giá trị cơ thể từ sự kiện

const {path, queryStringParameter, headers, body} = event;


1

Hàm Lambda mong đợi đầu vào JSON, do đó phân tích chuỗi truy vấn là cần thiết. Giải pháp là thay đổi chuỗi truy vấn thành JSON bằng Mẫu ánh xạ.
Tôi đã sử dụng nó cho C # .NET Core, vì vậy, đầu vào dự kiến ​​sẽ là một JSON với tham số "queryStringParameter".
Thực hiện theo 4 bước dưới đây để đạt được điều đó:

  1. Mở mẫu ánh xạ của tài nguyên API Gateway của bạn và thêm application/jsonnội dung mới :

Mẫu ánh xạ API Gateway

  1. Sao chép mẫu bên dưới, phân tích chuỗi truy vấn vào JSON và dán nó vào mẫu ánh xạ:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. Trong API Gateway, hãy gọi hàm Lambda của bạn và thêm chuỗi truy vấn sau (ví dụ): param1=111&param2=222&param3=333

  3. Mẫu ánh xạ sẽ tạo đầu ra JSON bên dưới, đây là đầu vào cho hàm Lambda của bạn.

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. Bạn đã hoàn tất. Từ thời điểm này, logic của hàm Lambda của bạn có thể sử dụng các tham số chuỗi truy vấn.
    Chúc may mắn!


0

Bạn có thể sử dụng Lambda làm "Tích hợp proxy Lambda" , tham khảo [ https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda. html # api-gateway-proxy-integration-lambda-function-python] , các tùy chọn có sẵn cho lambda này là

Đối với Nodejs Lambda 'event.headers', 'event.pathParameter', 'event.body', 'event.stageVariables' và 'event.requestContext'

Đối với sự kiện Python Lambda ['tiêu đề'] ['tên người dùng'], v.v.



-1

Sau khi đọc một vài trong số những câu trả lời này, tôi đã sử dụng kết hợp nhiều câu trả lời vào tháng 8 năm 2018 để lấy thông số chuỗi truy vấn thông qua lambda cho python 3.6.

Đầu tiên, tôi đã đi đến API Gateway -> API của tôi -> tài nguyên (ở bên trái) -> Yêu cầu tích hợp. Ở phía dưới, chọn Bản đồ mẫu sau đó nhập loại nội dung application/json.

Tiếp theo, chọn mẫu Truyền yêu cầu phương thức mà Amazon cung cấp và chọn lưu và triển khai API của bạn.

Sau đó, lambda event['params']là cách bạn truy cập tất cả các tham số của bạn. Đối với chuỗi truy vấn:event['params']['querystring']

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.