게시글 작성, 조회 API

Byeonghyeon·2024년 11월 27일

관리자와 일반 유저를 구분했으니 이제 게시글 관련 API를 작성해보자

팀메이트에서 말하는 게시글이란 두 가지 종류가 있는데 관리자만 작성할 수 있는 공지사항, 누구나 작성 가능한 일반 게시글 두 가지이다.

우선 공지사항과 일반 게시글의 모델을 살펴보자

model Notice {
  id        Int      @id @default(autoincrement())
  title     String
  content   String
  postedadmin String
  createdAt DateTime @default(now())
}

model Post {
  id         Int       @id @default(autoincrement())
  title      String
  content    String
  posteduser String
  createdAt  DateTime  @default(now())
  comments   Comment[] // Post에 연결된 Comment 목록을 참조
}

Notice는 공지사항, Post는 일반 게시글이다.

두 개는 사실상 거의 같다.

postedadmin과 posteduser는 이름만 다를 뿐 같은 역할을 하니 제쳐두고, 다른점은 Post에는 Notice에는 없는 comments가 존재한다는 점이다.

이는 게시글에 댓글 기능을 추가하였기 때문에 게시글에 달린 댓글들을 저장하는 공간이다.

POST

export async function POST(req: Request) {
    try {
        const body = await req.json();
        if (body.action === "create") {
            const post = await prisma.post.create({
                data: { title: body.title, content: body.content, posteduser: body.posteduser },
            });
            return NextResponse.json(post, { status: 200 });
        }  else {
            return NextResponse.json({ error: "Invalid action specified" }, { status: 400 });
        }
    } catch (err) {
        console.error(err);
        return NextResponse.json({ error: "Failed to create post" }, { status: 500 });
    }
}

해당 코드는 일반 게시글 작성 API이다.

작성 요청을 받으면 클라이언트에서 전달 받은 title(제목)과 content(내용) 그리고 posteduser(작성자)를 Post 테이블에 저장한다.

export async function POST(req: Request) {
    try {
        const body = await req.json();
        const requestUser = req.headers.get("requestUser");

        if (!requestUser) {
            return NextResponse.json({ error: "User is required" }, { status: 400 });
        }

        if (!(await isAdmin(requestUser))) {
            return NextResponse.json({ error: "Unauthorized" }, { status: 403 });
        }

        if (body.action === "create") {
            const notice = await prisma.notice.create({
                data: { title: body.title, content: body.content, postedadmin: body.postedadmin },
            });
            return NextResponse.json(notice, { status: 200 });
        }  else {
            return NextResponse.json({ error: "Invalid action specified" }, { status: 400 });
        }
    } catch (err) {
        console.error(err);
        return NextResponse.json({ error: "Failed to create notice" }, { status: 500 });
    }
}

공지사항 작성 API도 기능은 일반 게시글과 같지만, 관리자를 검증하는 과정이 필요하다.

async function isAdmin(requestUser: string) {
    const user = await prisma.user.findUnique({
        where: { email: requestUser },
    });
    return user?.role === "admin";
}

isAdmin이라는 관리자 검증 메소드를 만들었다.

작성을 요청한 유저를 user 테이블에서 찾아서 해당 유저의 역할이 'admin'이라면 true를, 'user'라면 false를 반환한다.

export async function POST(req: Request) {
    try {
        const body = await req.json();
        const requestUser = req.headers.get("requestUser");

        if (!requestUser) {
            return NextResponse.json({ error: "User is required" }, { status: 400 });
        }

        if (!(await isAdmin(requestUser))) {
            return NextResponse.json({ error: "Unauthorized" }, { status: 403 });
        }

        if (body.action === "create") {
            const notice = await prisma.notice.create({
                data: { title: body.title, content: body.content, postedadmin: body.postedadmin },
            });
            return NextResponse.json(notice, { status: 200 });
        }  else {
            return NextResponse.json({ error: "Invalid action specified" }, { status: 400 });
        }
    } catch (err) {
        console.error(err);
        return NextResponse.json({ error: "Failed to create notice" }, { status: 500 });
    }
}

공지사항 작성 API도 기능은 일반 게시글과 같지만, 관리자를 검증하는 과정이 필요하다.

async function isAdmin(requestUser: string) {
    const user = await prisma.user.findUnique({
        where: { email: requestUser },
    });
    return user?.role === "admin";
}

공지사항 작성을 요청한 유저를 user 테이블에서 찾아 해당 유저의 역할이 'admin'이라면 true를, 'user'라면 false를 반환한다.

export async function POST(req: Request) {
    try {
        const body = await req.json();
        const requestUser = req.headers.get("requestUser");

        if (!requestUser) {
            return NextResponse.json({ error: "User is required" }, { status: 400 });
        }

        if (!(await isAdmin(requestUser))) {
            return NextResponse.json({ error: "Unauthorized" }, { status: 403 });
        }

        if (body.action === "create") {
            const notice = await prisma.notice.create({
                data: { title: body.title, content: body.content, postedadmin: body.postedadmin },
            });
            return NextResponse.json(notice, { status: 200 });
        }  else {
            return NextResponse.json({ error: "Invalid action specified" }, { status: 400 });
        }
    } catch (err) {
        console.error(err);
        return NextResponse.json({ error: "Failed to create notice" }, { status: 500 });
    }
}

다시 작성 API로 돌아와서

클라이언트에서는 title, content, postedadmin, requestUser를 전달한다.

requestUser가 없다면 에러 메시지를 반환하고, requestUser를 isAdmin 메소드를 통해 관리자인지 검증한 후 true를 반환 받았다면 공지사항을 작성하는 구조이다.

GET

조회 API는 공지사항과 일반 게시글이 같다.

게시글은 역할에 상관없이 누구나 다 조회를 할 수 있어야 하기 때문이다.

export async function GET(req: Request) {
    try {
        const { searchParams } = new URL(req.url);
        const id = searchParams.get("id");

        if (id) {
            // id가 존재하면 해당 id로 특정 게시글 조회
            const post = await prisma.post.findUnique({
                where: { id: Number(id) },
                include: {
                    comments: true, // comments 관계를 포함하여 조회
                },
            });

            if (!post) {
                return NextResponse.json({ error: "Post not found" }, { status: 404 });
            }

            return NextResponse.json(post, { status: 200 });
        } else {
            // id가 없으면 모든 게시글을 조회
            const posts = await prisma.post.findMany({
                orderBy: { createdAt: "desc" },
            });

            return NextResponse.json(posts, { status: 200 });
        }
    } catch (err) {
        console.error(err);
        return NextResponse.json({ error: "Failed to retrieve post(s)" }, { status: 500 });
    }
}

조회에는 두 가지 종류가 있다.

등록된 게시글을 모두 조회하는 것, 특정 게시글만 조회하는 것.

모두 조회하는 것은 '게시판 페이지'에서 필요하고 특정 게시글만 조회하는 것은 '게시글 페이지'에서 필요하다.

클라이언트에서 조회 요청을 받을 때 게시글(혹은 공지사항)의 id를 전달 받느냐, 전달 받지 않느냐로 이것을 구분하였다.

id를 전달받으면 해당 id에 해당하는 특정 게시글만 조회하는 것이므로 findUnique를 통해 해당 게시글을 반환하고,

id를 전달받지 않았다면 모든 게시글을 조회하는 것이므로 findMany를 통해 검색되는 모든 게시글을 반환하였다.

0개의 댓글