在本模块,您将开始使用已经部署的应用程序。在开始之前,让我们快速回顾一下应用程序中使用的 AWS 组件:
- Amazon Neptune 用于数据存储,您可以在其中将数据建模为图形数据。
- Amazon Cognito 用于用户注册和身份验证。
- AWS Lambda 用于计算处理。
- Amazon API Gateway 用于通过 HTTP 访问 Lambda 函数。
让我们看看这些组件是如何协同工作的。接下来的步骤中,您将使用这些组件,通过不同的应用程序端点来使用应用程序的功能。
首先从 Registration(注册)端点开始,新用户通过该端点注册并创建他们的账户。注册完用户之后,您可以使用 FetchUser(获取用户)端点来查看该用户的详细信息。
其次是 Login(登录)端点,用户可以使用客户端(如 Web 应用程序或移动应用程序)在此进行身份验证并获取身份令牌。
第三,使用 FetchUserRecommendations(获取用户推荐)端点来查找您应该关注的用户。
最后,使用 FollowUser(关注用户)端点开始关注其他用户。
完成时间
15 分钟
-
步骤 1:注册新用户
我们首先要了解的流程是 Registration(注册)端点。在此端点中,新用户通过提供登录信息(如用户名和密码)来注册。此外,新用户在注册时还可以表明自己的一些兴趣爱好。这有助于在用户初期就提供更多相关的推荐内容。
在我们了解这些端点的过程中,本指南会展示端点调用的相关代码片段。
您可以通过向 /users 端点发送 POST 请求来使用注册端点。您可以在 application/app.js 文件大约中间位置找到该端点的逻辑:
// Create user app.post('/users', wrapAsync(async (req, res) => { const validated = validateCreateUser(req.body) if (!validated.valid) { throw new Error(validated.message) } await createCognitoUser(req.body.username, req.body.password, req.body.email) const user = await createUser(req.body.username, req.body.interests) res.json(user) }))
处理函数首先会验证请求中传入的有效负载正文 (req.body)。如果验证通过,处理程序会在 Amazon Cognito 中创建用户,然后使用 createUser 函数在 Neptune 数据库中创建用户。
我们在 Amazon Cognito 模块中已经回顾了 createCognitoUser 函数,这里就不再赘述了。让我们看看 application/data/createUser.js 文件中的 createUser 函数。
// application/data/createUser.js const { g } = require('./utils') const createUser = async (username, interests) => { const user = await g.addV('User').property('username', username).next() const edgePromises = interests.map((interest) => { return g.V() .has('Interest', 'interest', interest) .as('interest') .V(user.value.id) .addE('InterestedIn').to('interest') .next() }) await Promise.all(edgePromises) return { username, interests } } module.exports = createUser
createUser 函数接受用户名和兴趣数组两个参数。该函数在 Neptune 数据库中创建用户,然后遍历兴趣数组,添加从用户顶点到兴趣顶点的 InterestedIn(感兴趣)边。
试试调用 Registration 端点来创建一个新用户。在终端中运行以下命令:
curl -X POST ${BASE_URL}/users \ -H 'Content-Type: application/json' \ -d '{ "username": "thefriendlyuser", "password": "Password1", "email": "test@email.com", "interests": ["Sports", "Nature", "Cooking"] }'
您应当会在终端看到以下输出结果:
{"username":"thefriendlyuser","interests":["Sports","Nature","Cooking"]}
太棒了!您已经成功创建了用户。
通过以下命令获取用户详情,检查用户是否创建成功,以及是否与其兴趣建立了连接:
curl -X GET ${BASE_URL}/users/thefriendlyuser
您应当会在终端看到以下输出结果:
{"username":"thefriendlyuser","friends":[],"interests":["Cooking","Nature","Sports"]}
太棒了!您可以看到用户的兴趣已经被保存了。您还可以看到该用户目前还没有好友。这个问题我们将在后续步骤中解决。
现在,让我们登录并获取身份令牌。
-
步骤 2:登录获取用户凭证
第二个端点是 Login(登录)端点。用户将向该端点提交用户名和密码,以获取身份令牌,该令牌将用于后续请求的身份验证。
为了处理身份验证和发放令牌,您的应用程序中设置了一个 /login 端点。处理函数位于 application/app.js 文件中,如下所示:
// Login app.post('/login', wrapAsync(async (req, res) => { const idToken = await login(req.body.username, req.body.password) res.json({ idToken }) }))
它要求请求的有效负载正文中包含 username 和 password 属性。然后调用 auth.js 文件中的辅助函数 login。如果登录成功,它会返回该用户的身份令牌。
让我们用您创建的用户来测试一下。在终端中运行以下命令:
curl -X POST ${BASE_URL}/login \ -H 'Content-Type: application/json' \ -d '{ "username": "thefriendlyuser", "password": "Password1" }'
您应当会在终端看到以下输出结果:
{"idToken":"eyJraWQiO…."}
该身份令牌会在后续请求中用于对用户进行授权。通过复制引号内的令牌值并运行以下命令,将身份令牌的值保存在 shell 中:
export ID_TOKEN=<idToken>
-
步骤 3:获取针对用户的推荐信息
目前您的新用户还没有任何好友。这对应用程序内的用户体验不太友好,所以我们希望帮助他们找到新的好友。为此,您可以生成一些推荐,让用户关注新的好友。
您的应用程序中有一个 FetchUserRecommendations(获取用户推荐)端点。该端点的代码如下所示:
// Fetch user recommendations app.get('/users/:username/recommendations', wrapAsync(async (req, res) => { const recommendations = await fetchUserRecommendations(req.params.username) res.json(recommendations) }))
处理函数从 URL 路径中获取用户名,并将其传递给 fetchUserRecommendations 函数来生成推荐。
fetchUserRecommendations 函数位于 application/data/fetchUserRecommendations.js 文件中,内容如下所示:
const { g, local, values, desc, without, neq } = require('./utils') const fetchUserRecommendations = async (username) => { const friendsOfFriends = await g.V() .has('User', 'username', username).as('user') .out('Follows').aggregate('friends') .in_('Follows') .out('Follows').where(without('friends')) .where(neq('user')) .values('username') .groupCount() .order(local) .by(values, desc) .limit(local, 10) .next() const friendsWithInterests = await g.V() .has('User', 'username', username).as('user') .out('InterestedIn') .in_('InterestedIn') .out('Follows') .where(neq('user')) .values('username') .groupCount() .order(local) .by(values, desc) .limit(local, 10) .next() return { username, friendsOfFriends, friendsWithInterests } } module.exports = fetchUserRecommendations
fetchUserRecommendations 函数接受一个用户名参数,然后执行您在前面模块中看到的两种推荐策略。该函数会查找该用户好友的好友,以及有共同兴趣的好友。并返回这两种策略的结果。
让我们来试试这个端点。在终端中运行以下命令:
curl -X GET ${BASE_URL}/users/thefriendlyuser/recommendations
您应当会在终端看到以下输出结果:
{"username":"thefriendlyuser","friendsOfFriends":[],"friendsWithInterests":[["thardy",21],["michaelunderwood",20],["paullaurie",19],["ocarrillo",16],["paulacruz",16],["bergjames",16],["petersonchristina",15],["annette32",15],["evanewing",14],["hortonamy",14]]}
太棒了!您可以为该用户生成推荐了。
注意,您收到了 friendsWithInterests(有共同兴趣的好友)的推荐结果,但没有 friendsOfFriends(好友的好友)的推荐。这是因为您的用户目前还没有任何好友!
在下一步中,您将关注您的第一个好友。
-
步骤 4:关注好友
在此步骤中,您将关注第一个好友。
关注用户的端点是 POST /users/:username/friends,其处理函数的代码在 application/app.js 文件中,如下所示:
// Follow user app.post('/users/:username/friends', wrapAsync(async (req, res) => { const validated = validateFollowUser(req.body) if (!validated.valid) { throw new Error(validated.message) } const token = await verifyToken(req.header('Authorization')) if (token['cognito:username'] != req.params.username) { throw new Error('Unauthorized') } const friendship = await followUser({ follower: req.params.username, friend: req.body.username }) res.json(friendship) }))
这里将执行一些操作。首先验证请求的有效负载正文,确保其中包含 username 属性。其次,处理函数验证传入的 Authorization 标头,确保其与 URL 路径中的用户名值匹配。如果请求通过了验证和授权,就调用 followUser 函数添加关注关系。
在上一步中,您看到了一些推荐给该用户的好友。我们选择其中评分最高的一位,并关注该用户。
您可以使用以下命令关注该用户:
curl -X POST ${BASE_URL}/users/thefriendlyuser/friends \ -H 'Content-Type: application/json' \ -H "Authorization: ${ID_TOKEN}" \ -d '{ "username": "thardy" }'
您应当会在终端看到以下输出结果:
{"follower":"thefriendlyuser","friend":"thardy"}
成功了!您关注了您的第一个好友!
让我们再次获取您的用户详情,确保关注关系已存入数据库:
curl -X GET ${BASE_URL}/users/thefriendlyuser
您应当会在终端看到以下输出结果:
{"username":"thefriendlyuser","friends":["thardy"],"interests":["Sports","Cooking","Nature"]}
太棒了!现在,在用户的好友列表结果中出现了 thardy!
最后,让我们看看推荐更新了没有:
{"username":"thefriendlyuser","friendsOfFriends":[["michaelunderwood",8],["paullaurie",7],["morenojason",6],["paulacruz",6],["warrenpaul",5],["pricelucas",5],["ocarrillo",5],["hlowe",5],["clynch",5],["douglasrichard",5]],"friendsWithInterests":[["thardy",24],["michaelunderwood",20],["paullaurie",19],["ocarrillo",16],["paulacruz",16],["bergjames",16],["petersonchristina",15],["annette32",15],["evanewing",14],["hortonamy",14]]}
成功了!请注意,由于您的用户现在有了一些好友,该用户已经收到了 friendsOfFriends(好友的好友)的推荐。
在本模块中,通过使用可用的端点,您了解了各个组件是如何协同工作的。首先,您在应用程序中注册了一个新用户,并通过获取该用户信息,确保所有详细信息都已保存。其次,您使用登录端点获取了用户的身份令牌,客户端可以使用该令牌对用户进行身份验证。第三,您获取了该用户的好友推荐。然后,您根据这些推荐关注了第一个用户。在关注该用户后,您验证了好友关系已被保存,推荐也相应地更新了。
在下一个模块中,您将清理在本教程中创建的资源。