Instagramクローンエンコーディング5日目-BE
27273 ワード
#2.6 Followers
@Relationを使用して、一方向関係の関係を指定できます.
たとえば、BでAに従うと、AのFolwersに自動的にBが追加されます.
A.followers[ B ]
B.following[ A ]
schema.prismaでユーザーモデルに追従者と追従者を追加し、移行します.
ユーザー名でフォロー
接続の代わりにdisconnectを使用すると、接続が切断されます.すなわち、unfollow.
includeはあなたに欲しい関係を持たせます.
prismaは、データベースに大量のデータをロードするとサーバに負担をかけるため、ロード関係はほとんどありません.
少量のデータをインポートする場合は、includeで直接ロードできます.
上述したように、一度に複数のデータが読み込まれ、1ページずつ読み込まれることをページングと呼ぶ.
Paginationには2種類あります.
Offset Pagination
利点:必要なページに移動できます.
欠点:200000個のデータをスキップして10個のデータをインポートする場合は、200000個のデータをインポートする必要があります.
長所:規模を拡大しやすい.(無限スクロール用)
欠点:必要なページに移動できません.
LastIdを取得し、最後のIDからskipまで、次からtake数を取得します.
最初からlastidがなければskipは0,cursorは無である.
計算フィールドはgraphqlsechemaで定義されていますが、データベースにはありません.要求が受信されるたびに計算されます.
queryでuserを要求するとgraphqlはDBからuserを取得し、データベースにないフィールドをチェックし、解析器で検索します.見つかった場合は、この解析器をDBからインポートしたuserとして実行します.
解析器の最初のパラメータはルートで、親を表します.親プレイヤーとトークンで登録したプレイヤーを比較することができます.
@Relationを使用して、一方向関係の関係を指定できます.
たとえば、BでAに従うと、AのFolwersに自動的にBが追加されます.
A.followers[ B ]
B.following[ A ]
schema.prismaでユーザーモデルに追従者と追従者を追加し、移行します.
//schema.prisma
model User {
.
.
. // relation끼리의 이름이 같아야한다.
followers User[] @relation("FollowRelation", references: [id])
following User[] @relation("FollowRelation", references: [id])
.
.
}
followUserのtypeDefsと解析器を作成します.ユーザー名でフォロー
//followUser.typeDefs.js
import { gql } from "apollo-server-express";
export default gql`
type followUserResult{
ok: Boolean!
error: String
}
type Mutation{
followUser(username: String!): followUserResult!
}
`;
接続時に接続できるのは、唯一のフィールドのみです.接続の代わりにdisconnectを使用すると、接続が切断されます.すなわち、unfollow.
//followUser.resolver.js
const resolverFn = async (_, { username }, { loggedInUser }) => {
const isUser = client.user.findUnique({ where: { username } });
if (!isUser) {
return {
ok: false,
error: "That user does not exist",
};
}
await client.user.update({
where: {
id: loggedInUser.id,
},
data: {
following: {
connect: {
username,
}
}
}
});
return {
ok: true
};
};
#2.7 See Followers & Followingincludeはあなたに欲しい関係を持たせます.
prismaは、データベースに大量のデータをロードするとサーバに負担をかけるため、ロード関係はほとんどありません.
少量のデータをインポートする場合は、includeで直接ロードできます.
//seeProfile.resolvers.js
import client from "../../client";
export default {
Query: {
seeProfile: (_, { username }) => client.user.findUnique({
where: {
username,
},
include: {
following: true,
followers: true,
}
})
}
};
#2.8 Paginations上述したように、一度に複数のデータが読み込まれ、1ページずつ読み込まれることをページングと呼ぶ.
Paginationには2種類あります.
Offset Pagination
利点:必要なページに移動できます.
欠点:200000個のデータをスキップして10個のデータをインポートする場合は、200000個のデータをインポートする必要があります.
//seeFollowers.resolvers.js
import client from "../../client"
export default {
Query: {
seeFollowers: async (_, { username, page }) => {
const isUser = await client.user.findUnique({
where: { username }, select: { id: true }
}); //user 존재여부만 확인할 때는 user의 모든 data를 가져오지 않고 id만 가져온다.
if (!isUser) {
return {
ok: false,
error: "User is not found"
};
}
const followers = await client.user
.findUnique({ where: { username } })
.followers({
take: 5,
skip: (page - 1) * 5,
});
//user들 중 username을 following한 사람 수를 찾는 query
const totalFollowers = await client.user.count({
where: { following: { some: { username, } } }
});// 배열을 다 가져올 필요 없이 개수를 세고 count한 수만 가져온다.
return {
ok: true,
followers,
totalPages: Math.ceil(totalFollowers / 5),
};
}
}
};
Cursor-based Pagination長所:規模を拡大しやすい.(無限スクロール用)
欠点:必要なページに移動できません.
LastIdを取得し、最後のIDからskipまで、次からtake数を取得します.
最初からlastidがなければskipは0,cursorは無である.
// seeFollowing.resolvers.js
import client from "../../client"
export default {
Query: {
seeFollowing: async (_, { username, lastId }) => {
const isUser = await client.user.findUnique({ where: { username }, select: { id: true } });
if (!isUser) {
return {
ok: false,
error: "User is not found"
};
}
const following = await client.user.findUnique({ where: { username } }).following({
take: 5,
skip: lastId ? 1 : 0,
...(lastId && { cursor: { id: lastId } })
});
return {
ok: true,
following,
};
}
}
};
#2.9 Computed Field計算フィールドはgraphqlsechemaで定義されていますが、データベースにはありません.要求が受信されるたびに計算されます.
queryでuserを要求するとgraphqlはDBからuserを取得し、データベースにないフィールドをチェックし、解析器で検索します.見つかった場合は、この解析器をDBからインポートしたuserとして実行します.
解析器の最初のパラメータはルートで、親を表します.親プレイヤーとトークンで登録したプレイヤーを比較することができます.
// users.resolvers.js
import client from "../client";
export default {
User: {
totalFollowing: ({ id }) => //following 수
client.user.count({
where: {
followers: {
some: {
id,
}
}
}
}),
totalFollowers: ({ id }) => //follower 수
client.user.count({
where: {
following: {
some: {
id,
}
}
}
}), //user가 로그인한 자신인지 확인
isMe: ({ id }, _, { loggedInUser }) => {
if (!loggedInUser) {
return false;
}
return id === loggedInUser.id;
}, // user가 follow한 사람인지 확인
isFollowing: async ({ id }, _, { loggedInUser }) => {
if (!loggedInUser) {
return false;
}
const exist = await client.user.count({
where: {
username: loggedInUser.username,
following: {
some: {
id
}
}
}
});
return Boolean(exist);
}
}
};
Reference
この問題について(Instagramクローンエンコーディング5日目-BE), 我々は、より多くの情報をここで見つけました https://velog.io/@pjoon357/인스타그램-클론코딩-5일차テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol