Объединение нескольких запросов в одну функцию AWS лямбда - PullRequest
0 голосов
/ 17 ноября 2018

В моей таблице DynamoDB есть элементы с userA (MyUser), следующие за UserB (myFriends ..)

Primary-------|---- Srotkey---|---FriendID---|
 Myid.....       Friend-01        22223333

в той же таблице у меня также есть профили пользователей ..

Primary-------|---- Srotkey---|----Name----|
 Myid.....       Friend-01
 22223333          Profile         Rose    

Теперь я хочу иметь функцию для возврата профиля моего друга. Я полагаю, что моя лямбда-функция «getFriendProfile» должна выполнить два запроса, получить идентификатор человека, за которым я следую в первом запросе, а затем использовать этот результат для извлечения ее профиля во втором запросе.

Я знаю, как получить эти результаты по отдельности, но я не знаю, как их объединить и объединить их в одну функцию.

Первый запрос (getPeopleIFollow)

module.exports.handler = async (event, context, callback) => {

    const _userID = event.userID;

    var params = {
    TableName: "mytableName",
    ProjectionExpression: "FriendID",
    KeyConditionExpression: "#tp = :userId and begins_with(#sk, :skv)",
    ExpressionAttributeNames: {
      "#tp": "userId",
      "#sk": "Sortkey",
    },
    ExpressionAttributeValues: {
      ":userId": { "S": _userID },
      ":skv": { "S": "Friend" },

    }

    }
var Friend_ID;

try {

let data = await dynamodb.query(params).promise();

data.Items.map(
  (dataField) => {

  Friend_ID = dataField.FriendID.S,


  }

);

   callback(null, Friend_ID );

  }
  catch (error) {
    console.log(error);

    callback(error);
  }

};

Моя другая функция выглядит очень похоже на первую .. getProfileNames ..

module.exports.handler = async (event, context, callback) => {

    const _userID = event.myfriendID;

    var params = {
    TableName: "mytableName",
    ProjectionExpression: "Name",
    KeyConditionExpression: "#tp = :userId and begins_with(#sk, :skv)",
    ExpressionAttributeNames: {
      "#tp": "userId",
      "#sk": "Sortkey",
    },
    ExpressionAttributeValues: {
      ":userId": { "S": _userID },
      ":skv": { "S": "Profile" },

    }

    }
try {

let data = await dynamodb.query(params).promise();

const items = data.Items.map(
  (dataField) => {

      return {
        friend_name: dataField.Name.S,

    }

  }


);

   callback(null, items );

  }
  catch (error) {
    console.log(error);

    callback(error);
  }

};

1 Ответ

0 голосов
/ 18 ноября 2018

Хранение функциональности отдельно от каждой лямбды - это действительно хороший способ упорядочить код.Таким образом, вы можете оставить свой код таким, какой он есть, и вызывать лямбду getProfileNames для каждого из результатов getPeopleIFollow.

Я думаю, что это также хорошая идея - абстрагироваться как можно больше от вашего обработчика.так что становится легко следовать на высоком уровне.Поэтому в следующих примерах предполагается, что ваш код находится в других функциях, которые возвращают обещания.

(непроверенный код)

module.exports.handler = async (event, context, callback) => {
    const _userID = event.userID;
    try {
        const userFriends = await getUserFriends(userId);
        const friendProfiles = await getFriendProfiles(userFriends);
        callback(null, friendProfiles );
    } catch (error) {
        console.log(error);
        callback(error);
    }
}

Лямбда-вызов происходит в getFriendProfiles, который использует Promise.all для вызова лямбда-выражений для каждогоотдельный запрос friendProfile.

(непроверенный код)

function getFriendProfiles(userFriends){
    return Promise.all(userFriends.map(userFriend => {
        const params = {
            ClientContext: "MyApp", 
            FunctionName: "MyFunction", 
            InvocationType: "RequestResponse", // important, you choose this so you get a response otherwise (eg if you choose the 'Event' InvocationType) I think the promise will resolve once the invocation is successful
            LogType: "Tail", 
            Payload: JSON.stringify({ myfriendID: userFriend }), // I think this is right, I usually use pathParameters or body for my payloads
            Qualifier: "1"
        };
        lambda.invoke(params).promise();
    });
}

Сказав все это, мы видим, что это количество запросов к базе данных состоит в том, что, возможно, эта схема DynamoDb не самая эффективная.Это может быть случай, когда indexes может быть полезным, или даже использование RDS, а не DynamodB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...