Skip to content

3. Restful API로 리팩토링 #4

@KeonHee

Description

@KeonHee

Restful API로 리팩토링

  • 블로그 리스트 / 생성 / 수정 / 삭제를 Restful API로 리팩토링
  • Client에서 axios로 비동기 요청

1. Blog Controller 리팩토링

  • Rest API 구현을 위한 Controller 생성: BlogApiController
    • 리스트: public List<Blog> list(@RequestParam long creatorId)
    • 생성: public Blog create(@RequestParam long creatorId, @RequestBody Blog blog)
    • 수정: public Blog update(@RequestParam long creatorId, @PathVariable long id, @RequestBody Blog blog)
    • 삭제: public void delete(@RequestParam long creatorId, @PathVariable long id)
  • 기존에 사용하던 BlogController는 html 페이지만 리턴
    • 필요 없어진 로직들 삭제

2. Html 페이지 변경

  • 복붙해서 사용하세요

블로그 리스트

blogList.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container">
    <div>
        <h1><span th:text="${name}"/>의 블로그</h1>
        <p>
            <a th:href="@{/blogs/new(creatorId=${creatorId})}">생성</a>
        </p>
        <table>
            <thead>
            <tr>
                <th>#</th>
                <th>제목</th>
                <th>내용</th>
                <th></th>
                <th></th>
            </tr>
            </thead>
            <tbody id="blogs"></tbody>
        </table>
        <input type="hidden" id="creatorId" th:value="${creatorId}">
    </div>
</div> <!-- /container -->
</body>
<script>
    $(function () {
        const creatorId = $("#creatorId").val();
        axios({
            method: 'get',
            url: `/v1/api/blogs?creatorId=${creatorId}`,
            headers: {
                "Content-Type": `application/json`,
            },
        }).then(res => {
            const blogsContainer = $("#blogs")
            const blogs = res.data;
            for (const blog of blogs) {
                blogsContainer.append(
                    `<tr id="blog-${blog.id}">
                         <td>${blog.id}</td>
                         <td>${blog.title}</td>
                         <td>${blog.contents}</td>
                         <td>
                            <a type="button" href="/blogs/update?blogId=${blog.id}&creatorId=${creatorId}">
                                <button>수정</button>
                            </a>
                         </td>
                    </tr>`)
                const row = $(`#blog-${blog.id}`);

                // 삭제 버튼 추가
                const deleteBtn = $(`<button>삭제</button>`);
                deleteBtn.click(() => {
                    axios({
                        method: 'delete',
                        url: `/v1/api/blogs/${blog.id}?creatorId=${creatorId}`,
                    }).then(() => {
                        console.log(`${blog.id} 삭제 완료`);
                        row.remove();
                    })
                })
                row.append(deleteBtn);
            }
        })
    });
</script>
</html>

블로그 생성

createBlogForm.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container">
    <h1><span th:text="${name}"/>의 블로그</h1>
    <div>
        <div class="form-group">
            <label for="title">제목</label>
            <input type="text" id="title" name="title" placeholder="제목을 입력하세요">
        </div>
        <div class="form-group">
            <label for="contents">내용</label>
            <textarea id="contents" name="contents" placeholder="내용을 입력하세요"></textarea>
        </div>
        <button id="register-btn">등록</button>
    </div>
    <input type="hidden" id="creatorId" name="creatorId" th:value="${creatorId}">
</div> <!-- /container -->
</body>
<script>
    $(function () {
        const creatorId = $("#creatorId").val();
        $("#register-btn").on("click", () => {
            const title = $("#title").val();
            const contents = $("#contents").val();

            axios({
                method: 'post',
                url: `/v1/api/blogs?creatorId=${creatorId}`,
                headers: {
                    "Content-Type": `application/json`,
                },
                data: {
                    title: title,
                    contents: contents,
                    creatorId: creatorId
                }
            }).then(() => {
                window.location.href = `/blogs?creatorId=${creatorId}`;
            })
        })
    });
</script>
</html>

블로그 수정

updateBlogForm.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container">
    <h1><span th:text="${name}"/>의 블로그</h1>
    <div id="blog"></div>
    <input type="hidden" id="creatorId" name="creatorId" th:value="${creatorId}">
    <input type="hidden" id="blogId" name="blogId" th:value="${blogId}">
</div> <!-- /container -->
</body>
<script>
    $(function () {
        const creatorId = $("#creatorId").val();
        const blogId = $("#blogId").val();
        axios({
            method: 'get',
            url: `/v1/api/blogs/${blogId}?creatorId=${creatorId}`,
            headers: {
                "Content-Type": `application/json`,
            },
        }).then(res => {
            const blog = res.data;

            $("#blog").append(
                `<div class="form-group">
                    <label for="title">제목</label>
                    <input type="text" id="title" name="title" placeholder="제목을 입력하세요" value="${blog.title}">
                </div>
                <div class="form-group">
                    <label for="contents">내용</label>
                    <textarea id="contents" name="contents" placeholder="내용을 입력하세요">${blog.contents}</textarea>
                </div>
                <button id="register-btn">등록</button>
            `);

            $("#register-btn").on("click", () => {
                const title = $("#title").val();
                const contents = $("#contents").val();

                axios({
                    method: 'put',
                    url: `/v1/api/blogs/${blogId}?creatorId=${creatorId}`,
                    headers: {
                        "Content-Type": `application/json`,
                    },
                    data: {
                        id: blogId,
                        title: title,
                        contents: contents,
                        creatorId: creatorId
                    }
                }).then(() => {
                    window.location.href = `/blogs?creatorId=${creatorId}`;
                })
            })
        })
    });
</script>
</html>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions