티스토리 뷰
1. 개요
- PHP Restful API 및 Swagger UI 제공을 위한 Silex 프레임워크 설치 및 셋팅 방법
- Silex 프레임워크, Swagger UI를 이용한 API 개발 방법
2. 셋팅
2.1. Silex 프레임워크 설치
vi /home/apps/php/lib/php.ini
- allow_url_fopen = Off
+ allow_url_fopen = On
mkdir /home/dsan/program/www/api
cd /home/dsan/program/www/api
curl -s https://getcomposer.org/installer | php
php composer.phar require silex/silex
php composer.phar require jdesrosiers/silex-swagger-provider
php composer.phar require jdesrosiers/silex-cors-provider
vi /home/apps/php/lib/php.ini
- allow_url_fopen = On
+ allow_url_fopen = Off
2.2. Swagger UI 설치
cd /home/dsan/program/www/api
wget https://github.com/swagger-api/swagger-ui/archive/v2.0.12.tar.gz
tar xvfz v2.0.12
mv swagger-ui-2.0.12/dist swagger
vi swagger/index.html
- url: "http://petstore.swagger.wordnik.com/api/api-docs",
+ url: "http://192.168.51.33/api/web/index.php/api/api-docs",
2.3. Httpd 설정
vi /home/apache/conf/extra/httpd-userdir.conf
+ <Directory "/home/dsan/program/www/api">
+ <Limit GET POST PUT DELETE OPTIONS PROPFIND>
+ Order allow,deny
+ Allow from all
+ </Limit>
+ <LimitExcept GET POST PUT DELETE OPTIONS PROPFIND>
+ Order deny,allow
+ Deny from all
+ </LimitExcept>
+ </Directory>
3. 개발
3.1. 디렉토리 구조
- 인덱스 : /home/dsan/program/www/web/index.php
- 컨트롤러 : /home/dsan/program/www/web/controllers/*
- 컨테이너 : /home/dsan/program/www/web/containers/*
3.2. 인덱스
- autoload를 이용한 라이브러리 로드
- Silex 어플리케이션 생성하고, Swagger 프로바이더 등록
- Request 시 json 데이터 파라메터 변환 처리
- require을 이용한 controller 소스 임포트 처리
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php require __DIR__ . "/../vendor/autoload.php"; $app = new Silex\Application(); $app["debug"] = true; $app->register(new JDesrosiers\Silex\Provider\SwaggerServiceProvider(), array( "swagger.srcDir" => __DIR__ . "/../vendor/zircote/swagger-php/library", "swagger.servicePath" => __DIR__ . "/", )); $app->register(new JDesrosiers\Silex\Provider\CorsServiceProvider(), array( "cors.allowOrigin" => "http://petstore.swagger.io", )); use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\ParameterBag; $app->before(function (Request $request) { if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) { $data = json_decode($request->getContent(), true); $request->request->replace(is_array($data) ? $data : array()); } }); require(__DIR__ . '/controllers/system/v1/api/ip_address.php'); $app->after($app["cors"]); $app->run(); | cs |
3.3. 컨트롤러
- Swagger 리소스 설정은 해당 형식에 맞게 주석으로 등록이 되어야하고, 모든 컨트롤러 파일에 포함 되어야함.
- 필요한 컨테이너 모델 임포트
- uri path에 해당하는 post, put, get, delete 메서드 등록하고, 컨테이너 모델에서 필요한 벨리데이션 체크하고, 컨테이너 모델을 수행한다.
- PHP Swagger 형식에 맞게 Operation을 등록해준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | <?php use Swagger\Annotations as SWG; /** * @SWG\Resource(basePath="http://192.168.51.33/api/web/index.php", resourcePath="/spec") */ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; require(str_replace('/controllers/', '/containers/', __FILE__)); /** * @SWG\Api( * path="/system/api/v1/ip_addresses", * @SWG\Operations( * @SWG\Operation( * method="POST", * nickname="system_ip", * summary="시스템 IP 추가", * notes="시스템 IP 추가", * responseClass="SystemApiV1IPAddressModel", * @SWG\Parameter( * name="variables", * description="IP 속성", * paramType="body", * required=True, * allowMultiple=False, * type="SystemApiV1IPAddressModel", * defaultValue="" * ), * @SWG\ResponseMessage( * code=200, * message="OK" * ), * @SWG\ResponseMessage( * code=400, * message="BAD REQUEST" * ), * @SWG\ResponseMessage( * code=404, * message="NOT FOUND" * ) * ) * ) * ) */ $app->post('/system/api/v1/ip_addresses', function (Request $request) use ($app) { $post = array( 'address' => $request->request->get('address'), 'version' => $request->request->get('version') ); $model = new SystemApiV1IPAddressModel($post); $post['id'] = $model->setIPAddress(); return $app->json($post, 200); }); /** * @SWG\Api( * path="/system/api/v1/ip_address/{ip_idx}", * @SWG\Operations( * @SWG\Operation( * method="PUT", * nickname="system_ip", * summary="시스템 IP 변경", * notes="시스템 IP 변경", * responseClass="SystemApiV1IPAddressModel", * @SWG\Parameter( * name="ip_idx", * description="인덱스", * paramType="path", * required=True, * allowMultiple=False, * type="integer", * defaultValue="" * ), * @SWG\Parameter( * name="variables", * description="IP 속성", * paramType="body", * required=True, * allowMultiple=False, * type="SystemApiV1IPAddressModel", * defaultValue="" * ), * @SWG\ResponseMessage( * code=200, * message="OK" * ), * @SWG\ResponseMessage( * code=400, * message="BAD REQUEST" * ), * @SWG\ResponseMessage( * code=404, * message="NOT FOUND" * ) * ) * ) * ) */ $app->put('/system/api/v1/ip_address/{ip_idx}', function (Request $request, $ip_idx) use ($app) { $put = array( 'idx' => $ip_idx, 'address' => $request->request->get('address'), 'version' => $request->request->get('version') ); $model = new SystemApiV1IPAddressModel($put); $model->setUpdateIPAddress(); return $app->json($put, 200); }); /** * @SWG\Api( * path="/system/api/v1/ip_address/{ip_idx}", * @SWG\Operations( * @SWG\Operation( * method="GET", * nickname="system_ip", * summary="시스템 IP 조회", * notes="시스템 IP 조회", * responseClass="SystemApiV1IPAddressModel", * @SWG\Parameter( * name="ip_idx", * description="인덱스", * paramType="path", * required=True, * allowMultiple=False, * type="integer", * defaultValue="" * ), * @SWG\ResponseMessage( * code=200, * message="OK" * ), * @SWG\ResponseMessage( * code=400, * message="BAD REQUEST" * ), * @SWG\ResponseMessage( * code=404, * message="NOT FOUND" * ) * ) * ) * ) */ $app->get('/system/api/v1/ip_address/{ip_idx}', function (Request $request, $ip_idx) use ($app) { $get = array( 'idx' => $ip_idx, ); $model = new SystemApiV1IPAddressModel($get); $data = $model->getIPAddress(); if (empty($data)) { $app->abort(404, "Post $ip_idx does not exist."); } return $app->json($data, 200); }); /** * @SWG\Api( * path="/system/api/v1/ip_address/{ip_idx}", * @SWG\Operations( * @SWG\Operation( * method="DELETE", * nickname="system_ip", * summary="시스템 IP 삭제", * notes="시스템 IP 삭제", * responseClass="SystemApiV1IPAddressModel", * @SWG\Parameter( * name="ip_idx", * description="인덱스", * paramType="path", * required=True, * allowMultiple=False, * type="integer", * defaultValue="" * ), * @SWG\ResponseMessage( * code=200, * message="OK" * ), * @SWG\ResponseMessage( * code=400, * message="BAD REQUEST" * ), * @SWG\ResponseMessage( * code=404, * message="NOT FOUND" * ) * ) * ) * ) */ $app->delete('/system/api/v1/ip_address/{ip_idx}', function (Request $request, $ip_idx) use ($app) { $delete = array( 'idx' => $ip_idx, ); $model = new SystemApiV1IPAddressModel($delete); $data = $model->getIPAddress(); if (empty($data)) { $app->abort(404, "Post $ip_idx does not exist."); } $model->setDeleteIPAddress(); return $app->json($data, 200); }); | cs |
3.4. 컨테이너
- Swagger 모델 설정은 해당 형식에 맞게 주석으로 등록이 되어야하고, 모든 컨테이너 파일에 포함되어야함.
- 모델 클래스 안에 Swagger 프로퍼트 설정을 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <?php use Swagger\Annotations as SWG; /** * @SWG\Resource(basePath="http://192.168.51.33/api/web/index.php",resourcePath="/spec") */ /** * @SWG\Model(id="SystemApiV1IPAddressModel",required="['address','version']") */ class SystemApiV1IPAddressModel { public $idx; /** * @SWG\Property(name="address",type="string") */ public $address; /** * @SWG\Property(name="version",type="integer") */ public $version; public function __construct($data) { $this->idx = $data['idx']; $this->address = $data['address']; $this->version = $data['version']; } public function __destruct() { unset($this->idx); unset($this->address); unset($this->version); } public function getIPAddress(){ return 1; } public function setIPAddress(){ return 1; } public function setUpdateIPAddress(){ return 1; } public function setDeleteIPAddress(){ return 1; } } | cs |
4. 참고
- https://github.com/silexphp/Silex
- https://github.com/jdesrosiers/silex-swagger-provider
- http://silex.sensiolabs.org/documentation
- http://sleep-er.co.uk/blog/2013/Creating-a-simple-REST-application-with-Silex/
- http://sleep-er.co.uk/blog/2014/Creating-a-simple-REST-application-with-Silex-part2/
- http://sleep-er.co.uk/blog/2014/Creating-a-simple-REST-application-with-Silex-part3/
- http://zircote.com/swagger-php/
'프로그래밍' 카테고리의 다른 글
airspeed를 사용한 템플릿 설정 관리 (0) | 2016.10.19 |
---|---|
pyparsing을 사용한 bacula 설정 파서 (0) | 2016.10.19 |
pyparsing을 사용한 json 파서 (0) | 2016.10.18 |
Python 이미지를 스트링으로 변환 (0) | 2016.09.02 |
Python 리소스 제한 (0) | 2016.08.10 |
댓글
warpmemory
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
페이지
TAG
- limits
- File
- 번역
- Ansible
- code
- httpd
- client
- RESTful
- command
- Web
- Module
- Windows
- PowerShell
- deview
- Linux
- apache
- configuration
- monitoring
- 이슈처리
- 명령어
- mysql
- 예제
- MariaDB
- error
- check
- Python
- 코드
- 외부링크
- example
- engineering
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함