Yii2 Advanced에서 인증이 포함된 버전 관리 REST API 구축

발행: (2026년 6월 9일 PM 02:51 GMT+9)
7 분 소요
원문: Dev.to

출처: Dev.to

Yii2 Advanced는 프론트엔드, 백엔드, 콘솔, 그리고 common에 공유 코드를 두는 별도 애플리케이션 구조를 제공합니다. 기본적으로 API 애플리케이션은 포함되어 있지 않지만, Yii2 Advanced는 API를 추가하기 쉽게 설계되어 있습니다.
이 글에서는 별도의 API 애플리케이션을 만들고, REST 라우트를 설정하며, /v1/users, /v2/users 와 같은 버전이 있는 URL을 추가하고, 인증을 위한 기본 구조를 준비하는 과정을 설명합니다.

기본 Yii2 Advanced 프로젝트 구조

backend/
common/
console/
frontend/
vendor/
composer.json

API 애플리케이션 추가

프론트엔드와 백엔드와 같은 레벨에 새로운 api 폴더를 생성합니다.

api/

추가 후 전체 구조는 다음과 같습니다.

api/
backend/
common/
console/
frontend/
vendor/
composer.json

api 폴더 내부 구조

api/
  config/
    main.php
    main-local.php
    params.php
  controllers/
  modules/
  runtime/
  web/
    index.php

api/web 폴더가 API 애플리케이션의 공개 문서 루트가 됩니다.

api/web/index.php

run();

위 코드는 Yii를 부트스트랩하고, 공유 common 설정과 API 전용 설정을 로드합니다.

api/config/main.php

return [
    'id' => 'app-api',
    'basePath' => dirname(__DIR__),
    'controllerNamespace' => 'api\controllers',

    'components' => [
        'request' => [
            'csrfParam' => '_csrf-api',
            'parsers' => [
                'application/json' => yii\web\JsonParser::class,
            ],
        ],

        'response' => [
            'format' => yii\web\Response::FORMAT_JSON,
        ],

        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                'GET /' => 'site/index',
            ],
        ],
    ],
];

핵심 포인트

  • parsers

    'parsers' => [
        'application/json' => yii\web\JsonParser::class,
    ],

    → JSON 요청 본문을 Yii2가 읽을 수 있게 해줍니다.

  • response

    'response' => [
        'format' => yii\web\Response::FORMAT_JSON,
    ],

    → API 응답이 기본적으로 JSON 형태로 반환됩니다.

api/config/main-local.php

return [
    'components' => [
        'request' => [
            'cookieValidationKey' => 'generate-a-random-secret-key-here',
        ],
    ],
];

cookieValidationKey에는 실제 무작위 문자열을 넣어 주세요.

api/config/params.php

return [
    'status' => 'ok',
    'app' => 'api',
];

위와 같은 URL 규칙을 추가하면

'rules' => [
    'GET /' => 'site/index',
],

다음 주소에 접속했을 때

https://api.yourdomain.com/

또는 로컬에서는

http://localhost:8080/

다음과 같은 JSON 응답을 확인할 수 있습니다.

{
  "status": "ok",
  "app": "api"
}

URL 규칙 위치

urlManager 컴포넌트 안에 규칙을 넣어야 합니다.

'components' => [
    'urlManager' => [
        'enablePrettyUrl' => true,
        'showScriptName' => false,
        'rules' => [
            'GET /' => 'site/index',
        ],
    ],
],

규칙 배열은 components.urlManager 내부에 있어야 하며, 최상위 레벨에 두면 안 됩니다.

Yii2 REST URL 규칙

REST URL 규칙을 사용하면 표준 REST 엔드포인트를 자동으로 생성할 수 있습니다.

기본 예시

[
    'class' => yii\rest\UrlRule::class,
    'controller' => 'user',
]

위 설정은 다음과 같은 라우트를 만들어 줍니다.

HTTP 메서드URL
GET/users
GET/users/123
POST/users
PUT/users/123
PATCH/users/123
DELETE/users/123

Yii2는 컨트롤러 이름을 복수형으로 자동 변환합니다. (user → /users, product → /products 등)

여러 컨트롤러를 한 번에 등록

[
    'class' => yii\rest\UrlRule::class,
    'controller' => [
        'user',
        'product',
        'order',
        'payment',
        'notification',
    ],
],

각 컨트롤러마다 표준 REST URL이 자동으로 생성됩니다.

비표준 엔드포인트 – extraPatterns 사용

[
    'class' => yii\rest\UrlRule::class,
    'controller' => 'auth',
    'extraPatterns' => [
        'POST login' => 'login',
        'POST logout' => 'logout',
        'POST refresh-token' => 'refresh-token',
    ],
],

위 설정은 다음 라우트를 추가합니다.

  • POST /auth/login
  • POST /auth/logout
  • POST /auth/refresh-token

대부분의 엔드포인트는 REST 컨트롤러만 정의하면 자동으로 생성되며, 커스텀 라우트는 필요할 때만 extraPatterns에 추가하면 됩니다.

전체 URL 예시

API 베이스 URL이 https://api.yourdomain.com이라면:

로컬 환경에서는 http://localhost:8080을 사용합니다.

주의: pretty URL이 올바르게 설정되지 않으면 index.php가 URL에 포함될 수 있습니다.

http://localhost:8080/index.php/users
http://localhost:8080/index.php/auth/login

버전이 있는 API URL 구현 (모듈 사용)

버전이 있는 API를 만들 때는 Yii2 모듈을 활용하는 것이 권장됩니다.

디렉터리 구조

api/
  modules/
    v1/
      Module.php
      controllers/
        UserController.php
    v2/
      Module.php
      controllers/
        UserController.php

api/modules/v1/Module.php

<?php
namespace api\modules\v1;

use yii\base\Module as BaseModule;

class Module extends BaseModule
{
    public $controllerNamespace = 'api\modules\v1\controllers';
}

api/config/main.php에 모듈 등록

'modules' => [
    'v1' => [
        'class' => api\modules\v1\Module::class,
    ],
    'v2' => [
        'class' => api\modules\v2\Module::class,
    ],
],

components.urlManager.rules에 버전별 REST 규칙 추가

'rules' => [
    [
        'class' => yii\rest\UrlRule::class,
        'controller' => [
            'v1/user',
            'v1/product',
            'v1/order',
        ],
    ],
    [
        'class' => yii\rest\UrlRule::class,
        'controller' => [
            'v2/user',
            'v2/product',
            'v2/order',
        ],
    ],
],

위 설정으로 Yii2는 다음과 같은 매핑을 수행합니다.

  • api/modules/v1/controllers/UserController.php/v1/users
  • api/modules/v2/controllers/UserController.php/v2/users

인증 전용 컨트롤러 예시 (v1/auth)

api/modules/v1/controllers/AuthController.php

<?php
namespace api\modules\v1\controllers;

use yii\rest\Controller;

class AuthController extends Controller
{
    public function actions()
    {
        return [];
    }

    public function behaviors()
    {
        $behaviors = parent::behaviors();
        $behaviors['authenticator'] = [
            'class' => \yii\filters\auth\HttpBearerAuth::class,
        ];
        return $behaviors;
    }

    public function actionLogin()
    {
        // 로그인 로직
    }

    public function actionLogout()
    {
        // 로그아웃 로직
    }

    public function actionRefreshToken()
    {
        // 토큰 재발급 로직
    }
}

위 컨트롤러를 extraPatterns와 함께 선언하면 다음 라우트가 생성됩니다.

POST /v1/auth/login
POST /v1/auth/logout
POST /v1/auth/refresh-token

Bearer Token 인증 설정

REST 컨트롤러에 다음 코드를 추가하면 HttpBearerAuth를 사용할 수 있습니다.

0 조회
Back to Blog

관련 글

더 보기 »

Eidentic 소개

Today we're releasing Eidentic, an open-source TypeScript SDK for building AI agents with self-improving memory and the production fundamentals built in — not b...

Typescript의 타입

Introdução Tipos são uma forma de definir a “forma” ou o contrato dos dados que estamos usando no código. Pensando em Javascript puro, ele é dinâmico: você pode...