API 응답

현대 PHP 개발의 대부분은 단순히 자바스크립트가 많은 단일 페이지 애플리케이션에 데이터를 제공하기 위한 것인지 독립형 제품으로 API를 구축해야 합니다. CodeIgniter는 어떤 응답 유형에 대해 어떤 HTTP 상태 코드가 반환되어야 하는지 기억할 필요 없이 일반적인 응답 유형을 간단하게 만들기 위해 모든 컨트롤러와 함께 사용할 수 있는 몇 가지 특성을 제공합니다.

응답 예

다음 예는 컨트롤러 내의 일반적인 사용 패턴을 보여줍니다.

<?php

namespace App\Controllers;

use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Controller;

class Users extends Controller
{
    use ResponseTrait;

    public function createUser()
    {
        $model = new UserModel();
        $user  = $model->save($this->request->getPost());

        // Respond with 201 status code
        return $this->respondCreated();
    }
}

이 예에서는 일반 상태 메시지 ‘Created’와 함께 HTTP 상태 코드 201이 반환됩니다. 가장 일반적인 사용 사례에 대한 방법은 다음과 같습니다.

<?php

// Generic response method
$this->respond($data, 200);

// Generic failure response
$this->fail($errors, 400);

// Item created response
$this->respondCreated($data);

// Item successfully deleted
$this->respondDeleted($data);

// Command executed by no response required
$this->respondNoContent($message);

// Client isn't authorized
$this->failUnauthorized($description);

// Forbidden action
$this->failForbidden($description);

// Resource Not Found
$this->failNotFound($description);

// Data was not validated
$this->failValidationErrors($errors);

// Resource already exists
$this->failResourceExists($description);

// Resource previously deleted
$this->failResourceGone($description);

// Client made too many requests
$this->failTooManyRequests($description);

응답 유형 처리

이러한 방법 중 하나로 데이터를 전달하면 다음 기준에 따라 결과 형식을 지정하는 데이터 유형이 결정됩니다.

  • 형식은 컨트롤러의 $this->format 값에 따라 결정됩니다. null인 경우 클라이언트가 요청한 콘텐츠 유형과 협상을 시도하며 기본적으로 app/Config/Format.php$supportedResponseFormats 속성의 첫 번째 요소(기본적으로 JSON)를 사용합니다.

  • 데이터는 형식에 따라 형식화됩니다. 형식이 JSON이 아니고 데이터가 문자열인 경우 HTML로 처리되어 클라이언트에 다시 전송됩니다.

참고

v4.5.0 이전에는 버그로 인해 데이터가 문자열인 경우 형식이 JSON이더라도 HTML로 처리되었습니다.

사용되는 포맷터를 정의하려면 app/Config/Format.php를 편집하세요. $supportedResponseFormats에는 애플리케이션이 자동으로 응답 형식을 지정할 수 있는 MIME 유형 목록이 포함되어 있습니다. 기본적으로 시스템은 XML 및 JSON 응답의 형식을 지정하는 방법을 알고 있습니다.

<?php

namespace Config;

use CodeIgniter\Config\BaseConfig;

class Format extends BaseConfig
{
    public $supportedResponseFormats = [
        'application/json',
        'application/xml',
    ];

    // ...
}

참고

v4.7.0부터 app/Config/Format.php 파일을 편집하여 기본 JSON 인코딩 깊이를 변경할 수 있습니다. $jsonEncodeDepth 값은 최대 깊이를 정의하며 기본값은 512입니다.

이는 반환할 응답 유형을 결정하기 위해 Content Negotiation 중에 사용되는 배열입니다. 클라이언트가 요청한 것과 지원하는 것 사이에 일치하는 항목이 없으면 이 배열의 첫 번째 형식이 반환됩니다.

다음으로, 데이터 배열의 형식을 지정하는 데 사용되는 클래스를 정의해야 합니다. 이는 정규화된 클래스 이름이어야 하며 클래스는 CodeIgniter\Format\FormatterInterface을 구현해야 합니다. JSON과 XML을 모두 지원하는 포맷터는 기본적으로 제공됩니다.

<?php

namespace Config;

use CodeIgniter\Config\BaseConfig;

class Format extends BaseConfig
{
    public $formatters = [
        'application/json' => \CodeIgniter\Format\JSONFormatter::class,
        'application/xml'  => \CodeIgniter\Format\XMLFormatter::class,
    ];

    // ...
}

따라서 요청이 Accept 헤더에 JSON 형식의 데이터를 요청하는 경우 respond* 또는 fail* 메서드 중 하나를 전달하는 데이터 배열은 CodeIgniter\Format\JSONFormatter 클래스에 의해 형식이 지정됩니다. 결과 JSON 데이터는 클라이언트로 다시 전송됩니다.

수업 참고자료

setResponseFormat($format)
매개변수:
  • $format (string) – 반환할 응답 유형(json 또는 xml)

이는 응답에서 배열 형식을 지정할 때 사용할 형식을 정의합니다. $formatnull 값을 제공하면 콘텐츠 협상을 통해 자동으로 결정됩니다.

<?php

return $this->setResponseFormat('json')->respond(['error' => false]);
respond($data[, $statusCode = 200[, $message = '']])
매개변수:
  • $data (mixed) – 클라이언트에 반환할 데이터입니다. 문자열 또는 배열입니다.

  • $statusCode (int) – 반환할 HTTP 상태 코드입니다. 기본값은 200입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

이는 클라이언트에 응답을 반환하기 위해 이 특성의 다른 모든 메서드에서 사용되는 메서드입니다.

$data 요소는 문자열이거나 배열일 수 있습니다. 기본적으로 문자열은 HTML로 반환되는 반면, Content Negotiation에서 다른 형식으로 반환되어야 한다고 결정하지 않는 한 배열은 json_encode를 통해 실행되고 JSON으로 반환됩니다.

$message 문자열이 전달되면 응답 상태에 대한 표준 IANA 이유 코드 대신 사용됩니다. 그러나 모든 클라이언트가 사용자 정의 코드를 존중하는 것은 아니며 상태 코드와 일치하는 IANA 표준을 사용합니다.

참고

활성 응답 인스턴스에 상태 코드와 본문을 설정하므로 이는 항상 스크립트 실행의 최종 메서드여야 합니다.

fail($messages[, int $status = 400[, string $code = null[, string $message = '']]])
매개변수:
  • $messages (mixed) – 발생한 오류 메시지가 포함된 문자열 또는 문자열 배열입니다.

  • $status (int) – 반환할 HTTP 상태 코드입니다. 기본값은 400입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

클라이언트가 선호하는 형식의 다중 부분 응답입니다.

이는 실패한 응답을 나타내는 데 사용되는 일반적인 방법이며 다른 모든 “실패” 방법에서 사용됩니다.

$messages 요소는 문자열이거나 문자열 배열일 수 있습니다.

$status 매개변수는 반환되어야 하는 HTTP 상태 코드입니다.

많은 API가 사용자 정의 오류 코드를 사용하여 더 잘 제공되므로 사용자 정의 오류 코드를 세 번째 매개변수에 전달할 수 있습니다. 값이 없으면 $status과 동일합니다.

$message 문자열이 전달되면 응답 상태에 대한 표준 IANA 이유 코드 대신 사용됩니다. 그러나 모든 클라이언트가 사용자 정의 코드를 존중하는 것은 아니며 상태 코드와 일치하는 IANA 표준을 사용합니다.

응답은 status, codemessages의 세 가지 요소로 구성된 배열입니다. - status 요소에는 오류의 상태 코드가 포함되어 있습니다. - code 요소에는 사용자 정의 API 관련 오류 코드가 포함되어 있습니다. - messages 요소에는 오류 메시지 배열이 포함되어 있습니다.

오류 메시지 수에 따라 응답은 다음과 같습니다.

<?php

// Example response with a single error message
$response = [
    'status'   => 400,
    'code'     => '321',
    'messages' => [
        'error' => 'An error occurred',
    ],
];

// Example response with multiple error messages per field
$response = [
    'status'   => 400,
    'code'     => '321a',
    'messages' => [
        'foo' => 'Error message 1',
        'bar' => 'Error message 2',
    ],
];
respondCreated($data = null[, string $message = ''])
매개변수:
  • $data (mixed) – 클라이언트에 반환할 데이터입니다. 문자열 또는 배열입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

새 리소스가 생성될 때 사용할 적절한 상태 코드(일반적으로 201)를 설정합니다.

<?php

$user = $userModel->insert($data);

return $this->respondCreated($user);
respondDeleted($data = null[, string $message = ''])
매개변수:
  • $data (mixed) – 클라이언트에 반환할 데이터입니다. 문자열 또는 배열입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

이 API 호출의 결과로 새 리소스가 삭제될 때 사용할 적절한 상태 코드(일반적으로 200)를 설정합니다.

<?php

$user = $userModel->delete($id);

return $this->respondDeleted(['id' => $id]);
respondNoContent(string $message = 'No Content')
매개변수:
  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

서버에서 명령이 성공적으로 실행되었지만 클라이언트에 다시 보낼 의미 있는 응답(일반적으로 204)이 없을 때 사용할 적절한 상태 코드를 설정합니다.

<?php

sleep(1);

return $this->respondNoContent();
failUnauthorized(string $description = 'Unauthorized'[, string $code = null[, string $message = '']])
매개변수:
  • $description (string) – 사용자에게 표시되는 오류 메시지입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

사용자가 인증되지 않았거나 잘못된 인증을 받은 경우 사용할 적절한 상태 코드를 설정합니다. 상태 코드는 401입니다.

<?php

return $this->failUnauthorized('Invalid Auth token');
failForbidden(string $description = 'Forbidden'[, string $code=null[, string $message = '']])
매개변수:
  • $description (string) – 사용자에게 표시되는 오류 메시지입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

failUnauthorized()과 달리 이 메서드는 요청된 API 엔드포인트가 절대 허용되지 않을 때 사용해야 합니다. 승인되지 않음은 클라이언트가 다른 자격 증명을 사용하여 다시 시도하도록 권장된다는 의미입니다. 금지됨은 도움이 되지 않으므로 클라이언트가 다시 시도해서는 안 된다는 의미입니다. 상태 코드는 403입니다.

<?php

return $this->failForbidden('Invalid API endpoint.');
failNotFound(string $description = 'Not Found'[, string $code=null[, string $message = '']])
매개변수:
  • $description (string) – 사용자에게 표시되는 오류 메시지입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

요청한 리소스를 찾을 수 없을 때 사용할 적절한 상태 코드를 설정합니다. 상태 코드는 404입니다.

<?php

return $this->failNotFound('User 13 cannot be found.');
failValidationErrors($errors[, string $code=null[, string $message = '']])
매개변수:
  • $errors (mixed) – 사용자에게 표시할 오류 메시지 또는 메시지 배열입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

클라이언트가 보낸 데이터가 유효성 검사 규칙을 통과하지 못한 경우 사용할 적절한 상태 코드를 설정합니다. 상태 코드는 일반적으로 400입니다.

<?php

return $this->failValidationErrors($validation->getErrors());
failResourceExists(string $description = 'Conflict'[, string $code=null[, string $message = '']])
매개변수:
  • $description (string) – 사용자에게 표시되는 오류 메시지입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

클라이언트가 생성하려는 리소스가 이미 존재할 때 사용할 적절한 상태 코드를 설정합니다. 상태 코드는 일반적으로 409입니다.

<?php

return $this->failResourceExists('A user already exists with that email.');
failResourceGone(string $description = 'Gone'[, string $code=null[, string $message = '']])
매개변수:
  • $description (string) – 사용자에게 표시되는 오류 메시지입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

요청된 리소스가 이전에 삭제되어 더 이상 사용할 수 없을 때 사용할 적절한 상태 코드를 설정합니다. 상태 코드는 일반적으로 410입니다.

<?php

return $this->failResourceGone('That user has been previously deleted.');
failTooManyRequests(string $description = 'Too Many Requests'[, string $code=null[, string $message = '']])
매개변수:
  • $description (string) – 사용자에게 표시되는 오류 메시지입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

클라이언트가 API 엔드포인트를 너무 많이 호출한 경우 사용할 적절한 상태 코드를 설정합니다. 이는 일종의 제한이나 속도 제한으로 인해 발생할 수 있습니다. 상태 코드는 일반적으로 400입니다.

<?php

return $this->failTooManyRequests('You must wait 15 seconds before making another request.');
failServerError(string $description = 'Internal Server Error'[, string $code = null[, string $message = '']])
매개변수:
  • $description (string) – 사용자에게 표시되는 오류 메시지입니다.

  • $code (string) – 사용자 정의 API별 오류 코드입니다.

  • $message (string) – 반환할 사용자 정의 “이유” 메시지입니다.

반환:

Response 객체의 send() 메서드 값입니다.

서버 오류가 있을 때 사용할 적절한 상태 코드를 설정합니다.

<?php

return $this->failServerError('Server error.');

페이지 매김 응답

API 엔드포인트에서 페이지가 매겨진 결과를 반환할 때 paginate() 메서드를 사용하여 페이지 매김 정보와 함께 결과를 반환할 수 있습니다. 이는 클라이언트가 결과를 적절하게 페이징하는 데 필요한 모든 정보를 제공하는 동시에 API 전체에서 일관된 응답을 유지하는 데 도움이 됩니다.

사용 예

<?php

use App\Controllers\BaseController;
use App\Models\UserModel;
use CodeIgniter\API\ResponseTrait;

class UserController extends BaseController
{
    use ResponseTrait;

    public function index()
    {
        $model = model(UserModel::class)
            ->where('active', 1);

        return $this->paginate($model, 20);
    }
}

일반적인 응답은 다음과 같습니다.

{
    "data": [
        {
            "id": 1,
            "username": "admin",
            "email": "admin@example.com"
        },
        {
            "id": 2,
            "username": "user",
            "email": "user@example.com"
        }
    ],
    "meta": {
        "page": 1,
        "perPage": 20,
        "total": 2,
        "totalPages": 1
    },
    "links": {
        "self": "http://example.com/users?page=1",
        "first": "http://example.com/users?page=1",
        "last": "http://example.com/users?page=1",
        "next": null,
        "previous": null
    }
}

paginate() 메소드는 항상 결과를 data 요소로 래핑하고 클라이언트가 결과를 페이지화하는 데 도움이 되는 metalinks 요소도 포함합니다. 결과가 없으면 data 요소는 빈 배열이 되고 metalinks 요소는 여전히 존재하지만 결과가 없음을 나타내는 값이 있습니다.

빌더가 테이블 이름과 필요한 조인 또는 where 절로 올바르게 구성되어 있는 한 모델 대신 빌더 인스턴스를 전달할 수도 있습니다.

<?php

use App\Controllers\BaseController;
use CodeIgniter\API\ResponseTrait;

class UserController extends BaseController
{
    use ResponseTrait;

    public function index()
    {
        $builder = db_connect()
            ->table('users')
            ->where('active', 1);

        return $this->paginate(resource: $builder, perPage: 20);
    }
}

수업 참고자료

paginate(Model|BaseBuilder $resource, int $perPage = 20, ?string $transformWith = null)
매개변수:
  • $resource (Model|BaseBuilder) – 페이지를 매길 리소스(Model 또는 Builder 인스턴스)입니다.

  • $perPage (int) – 페이지당 반환할 항목 수입니다.

  • $transformWith (string|null) – 결과를 변환하기 위한 선택적 변환기 클래스 이름입니다.

지정된 리소스에서 페이지가 매겨진 응답을 생성합니다. 리소스는 모델 또는 빌더 인스턴스일 수 있습니다. 이 메소드는 요청의 쿼리 매개변수에서 현재 페이지를 자동으로 결정합니다. 응답에는 페이지 매김 상태에 대한 메타데이터 및 페이지를 탐색하기 위한 링크와 함께 페이지 매김 데이터가 포함됩니다.

변환기 클래스 이름과 함께 $transformWith 매개변수를 제공하는 경우 페이지가 매겨진 결과의 각 항목은 반환되기 전에 해당 변환기를 사용하여 변환됩니다. 이는 API 응답의 구조와 내용을 제어하는 ​​데 유용합니다. 변환기 생성 및 사용에 대한 자세한 내용은 API Transformers을 참조하세요.

변압기의 예:

<?php

use App\Controllers\BaseController;
use App\Models\UserModel;
use App\Transformers\UserTransformer;
use CodeIgniter\API\ResponseTrait;

class UserController extends BaseController
{
    use ResponseTrait;

    public function index()
    {
        $model = model(UserModel::class);

        return $this->paginate(resource: $model, perPage: 20, transformWith: UserTransformer::class);
    }
}