가수면
[Sanity] CRUD 본문
https://www.sanity.io/docs/connect-your-content-to-next-js
https://www.sanity.io/docs/js-client#multiple-mutations-in-a-transaction
그냥 진행하는 방식과 라이브러리 설치해 사용하는 방법이 있는데, 이번 글에선 라이브러리를 이용한 방법을 적는다.
npm install @sanity/client
기본 설정
각 키는 아래에서 확인 가능함 (토큰은 생성할 때 확인 가능함)
export const client = createClient({
projectId: process.env.SANITY_PROJECT_ID,
dataset: process.env.SANITY_DATASET,
useCdn: false, // 동적인 데이터가 주가 된다면 cdn 끄면 됨
apiVersion: "2023-03-20", // sanity 최신 API를 사용하기 위해 현재 날짜를 입력
token: process.env.SANITY_SECRET_TOKEN, // 데이터 읽기만 할 거면 사용 안 해도 되지만 수정할 거면 설정해야 함
});
기본 형태
export async function getPosts() {
const posts = await client.fetch('*[_type == "post"]')
return posts
}
export async function createPost(post: Post) {
const result = client.create(post)
return result
}
export async function updateDocumentTitle(_id, title) {
const result = client.patch(_id).set({title})
return result
}
생성
배열에 추가
export async function addComment(
postId: string,
userId: string,
comment: string
) {
return client
.patch(postId) // 데이터 id
.setIfMissing({ comments: [] }) // likes가 undefined라면 초기값 설정
.append('comments', [ // likes에 추가
{
comment,
author: { _ref: userId, _type: 'reference' },
},
])
.commit({ autoGenerateArrayKeys: true }); // 데이터 추가할 때 key 자동 설정 옵션
}
이미지 업로드
https://www.sanity.io/docs/assets
next 12버전
next 13버전
12버전에서는 node 환경에서 동작해 node 타입을 사용할 수 있었지만, 13버전에서는 edge에서도 동작할 수 있게 만들어야 해서 node타입을 사용할 수 없음
app폴더의 api 라우트 핸들러에서 client를 사용하면 현재까진 에러가 발생함. sanity에서 고칠 때까지 아래 방식으로 POST 요청을 직접 사용해야 함.
예시)
url 형식
'https://myProjectId.api.sanity.io/v2021-03-25/assets/images/myDataset'
export async function createPost(userId: string, text: string, file: Blob) {
return fetch(assetsURL, {
method: 'POST',
headers: {
'content-type': file.type,
authorization: `Bearer ${process.env.SANITY_SECRET_TOKEN}`,
},
body: file,
})
.then((res) => res.json())
.then((result) => {
return client.create(
{
_type: 'post',
author: { _ref: userId },
photo: { asset: { _ref: result.document._id } },
comments: [
{
comment: text,
author: { _ref: userId, _type: 'reference' },
},
],
likes: [],
},
{ autoGenerateArrayKeys: true }
);
});
}
회원가입 유저 추가
데이터에 추가할 때 중복되는 데이터가 있다면 추가 안 되도록 하는 로직이 필요함 (createIfNotExists)
export async function addUser({ id, username, email, name, image }: User) {
return client.createIfNotExists({
_id: id,
_type: "user",
username,
email,
name,
image,
following: [],
followers: [],
bookmarks: [],
});
}
읽기
GROQ
sanity의 오픈 소스 쿼리 언어. 원하는 정보를 groq를 이용해 client에 fetch를 날린다.
https://www.sanity.io/docs/query-cheat-sheet
export async function getPost(id: string) {
return client
.fetch(
`*[_type == "post" && _id == "${id}"][0]{
...,
"username": author->username,
"userImage": author->image,
"image": photo,
"likes": likes[]->username,
comments[]{comment, "username": author->username, "image": author->image},
"id":_id,
"createdAt":_creatdAt
}`
)
.then((post) => ({ ...post, image: urlFor(post.image) }));
}
수정
export async function addComment(
postId: string,
userId: string,
comment: string
) {
return client
.patch(postId) // 데이터 id
.setIfMissing({ comments: [] }) // likes가 undefined라면 초기값 설정
.append('comments', [ // likes에 추가
{
comment,
author: { _ref: userId, _type: 'reference' },
},
])
.commit({ autoGenerateArrayKeys: true }); // 데이터 추가할 때 key 자동 설정 옵션
}
삭제
export async function dislikePost(postId: string, userId: string) {
return client
.patch(postId)
.unset([`likes[_ref=="${userId}"]`])
.commit();
}
한번에 여러 데이터 변경
transaction을 사용
export async function follow(myId: string, targetId: string) {
return client
.transaction() //
.patch(myId, (user) =>
user
.setIfMissing({ following: [] })
.append('following', [{ _ref: targetId, _type: 'reference' }])
)
.patch(targetId, (user) =>
user
.setIfMissing({ followers: [] })
.append('followers', [{ _ref: myId, _type: 'reference' }])
)
.commit({ autoGenerateArrayKeys: true });
}
export async function unfollow(myId: string, targetId: string) {
return client
.transaction() //
.patch(myId, (user) => user.unset([`following[_ref=="${targetId}"]`]))
.patch(targetId, (user) => user.unset([`followers[_ref=="${myId}"]`]))
.commit({ autoGenerateArrayKeys: true });
}
'React > 라이브러리' 카테고리의 다른 글
리액트에서 CKEditor5 사용 (0) | 2023.07.21 |
---|---|
리액트에서 네이버 스마트 에디터 구현 (0) | 2023.07.20 |
SWR (0) | 2023.06.20 |
Mongo DB (0) | 2023.06.15 |
NextAuth.js (0) | 2023.06.11 |
Comments