Laravel에서 Swagger를 사용해보자

임승범·2023년 3월 28일
0

Swagger를 사용해서 API 명세서 작성해보기


darkaonline/l5-swagger 설치하기

  • 설치
composer require darkaonline/l5-swagger
  • 삭제
composer remove darkaonline/l5-swagger

L5-Swagger 설정 파일과 뷰 파일 생성하기

php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"

해당 명령어를 입력하여 실행하면 config 폴더 아래 l5-swagger.php 파일이 생성됩니다.

그리고 /resources/view/vendor 아래에 l5-swagger 관련 뷰 파일이 생성됩니다.

/config/app.php 파일을 수정하여 provider을 설정합니다.

'providers' => [
    /*
    * Swagger
    */
    \L5Swagger\L5SwaggerServiceProvider::class
]

이 과정을 모두 마치고 웹서버를 실행하여 https://127.0.0.1:8000/api/documentation 로 접속하면 아래와 같은 화면이 나타날 것입니다.

현재 화면상에 표기된 에러는 api-docs.json 파일이 없어서 나타나는 오류인데 컨트롤러에 어노테이션을 작성하여 API 명세서가 성공적으로 출력되는 과정을 정리해보겠습니다.

OA 어노테이션 적용

먼저 프로젝트의 가장 베이스가 되는 컨트롤러에 해당 프로젝트의 명세서 정보 등을 입력합니다.

/**
* @OA\Info(
*     title="Example", version="0.1", description="Example API Documentation",
*     @OA\Contact(
*         email="example@test.com",
*         name="Example"
*     )
* )
*/
class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

그 다음, 명세서에 작성할 함수 상단에 명세서 상세 정보를 입력합니다.

    /**
     * @OA\Post (
     *     path="/boards",
     *     tags={"게시판"},
     *     summary="게시글 등록",
     *     description="게시글을 등록",
     *     @OA\RequestBody(
     *         description="게시글 정보",
     *         required=true,
     *         @OA\MediaType(
     *             mediaType="application/json",
     *             @OA\Schema (
     *                 @OA\Property (property="board_title", type="string", description="게시글 제목", example="공지사항입니다."),
     *                 @OA\Property (property="board_content", type="string", description="게시글 내용", example="공지사항 내용입니다.")
     *             )
     *         )
     *     ),
     *     @OA\Response(response="200", description="Success"),
     *     @OA\Response(response="400", description="Fail")
     * )
     */
    public function store(Request $request) {

        $request = $request->validate([
            'board_title' => 'required',
            'board_content' => 'required'
        ]);
        $this->board->create([
            'board_title' => $request['board_title'],
            'board_content' => $request['board_content'],
            'created_at' => now(),
            'updated_at' => null
        ]);

        return redirect()->route('board.index');
    }

    public function show(Board $board) {
        return view('boards.detail', compact('board'));
    }

    public function edit(Board $board) {
        return view('boards.edit', compact('board'));
    }

    /**
     * @OA\Put (
     *     path="/boards/{board_id}",
     *     tags={"게시판"},
     *     summary="게시글 수정",
     *     description="게시글을 수정",
     *     @OA\Parameter (name="board_id", in="path", description="게시글 PK"),
     *     @OA\RequestBody(
     *         description="게시글 정보",
     *         required=true,
     *         @OA\MediaType(
     *             mediaType="application/json",
     *             @OA\Schema (
     *                 @OA\Property (property="board_title", type="string", description="게시글 제목", example="공지사항입니다."),
     *                 @OA\Property (property="board_content", type="string", description="게시글 내용", example="공지사항 내용입니다.")
     *             )
     *         )
     *     ),
     *     @OA\Response(response="200", description="Success"),
     *     @OA\Response(response="400", description="Fail")
     * )
     */
    public function update(Board $board, Request $request) {
        $request = $request->validate([
            'board_title' => 'required',
            'board_content' => 'required'
        ]);
        $board->update([
            'board_title' => $request['board_title'],
            'board_content' => $request['board_content'],
            'updated_at' => now()
        ]);
        return redirect()->route('board.index');
    }

    /**
     * @OA\Delete (
     *     path="/boards/{board_id}",
     *     tags={"게시판"},
     *     summary="게시글 삭제",
     *     description="게시글을 삭제",
     *     @OA\Parameter (name="board_id", in="path", description="게시글 PK"),
     *     @OA\Response(response="200", description="Success"),
     *     @OA\Response(response="400", description="Fail")
     * )
     */
    public function destroy(Board $board) {
        $board->delete();
        return redirect()->route('board.index');
    }

해당 코드는 /boards 경로로 post 타입의 게시글 저장 기능과 /boards/{board_id} 경로로 put 타입의 게시글 수정 기능, /boards/{board_id} 경로로 delete 타입의 게시글 삭제 기능의 정보를 작성한 것입니다.

이렇게 작성한 후, 아래의 명령어로 명세서 파일을 만들어줍니다.

php artisan l5-swagger:generate

명령어를 실행 후 웹서버를 실행하여 https://127.0.0.1:8000/api/documentation 으로 접속하면 아래의 이미지처럼 명세서가 생성된 것을 확인할 수 있습니다.


profile
어제보다 더 많이 아는 개발자

2개의 댓글

comment-user-thumbnail
2023년 12월 12일

Required @OA\Info() not found 이슈가 있습니다
원인은 zircote/swagger-php4.8 버전 이슈로 확인됩니다
4.7.16로 다운그레이드를 하거나
composer require doctrine/annotations 해당 명령어를 입력하면 해결됩니다
참고문헌
https://github.com/DarkaOnLine/L5-Swagger/issues/553

1개의 답글