수색…
RESTFul API 사용
REST (Representational State Transfer)는 Roy Fielding이 2000 년에 도입하고 정의한 웹 개발에 사용되는 아키텍처 스타일입니다.
wiki에서보기 : REST 위키
HTTP 프로토콜 ( Wiki의 HTTP ), HTTP 요청 (GET, POST, PATCH, DELETE ...) / 응답 코드 (404, 400, 200, 201, 500 ...) 및 본문 구조를 기반으로합니다.
이것은 인터넷상의 다른 시스템에 데이터를 노출시키는 좋은 방법입니다.
로컬 데이터베이스에서 StackOverFlower (User)를 관리하기 위해 RESTFul API를 만들고 싶다고 가정 해보십시오.
예제를 만들어 보겠습니다!
Symfony 2.8 프레임 워크
- 웹 서버 :
로컬 컴퓨터에 웹 서버를 설치하고 구성해야합니다. Wamp 또는 Lamp 또는 Mamp : 최신 버전의 PHP가 있어야합니다 ( Symfony 요구 사항 !!! ).
- PHP cli 및 작곡가 :
PHP cli (시스템마다 다를 수 있음)를 구성하고, Google의 친구 인 Google에서이 "PHP cli [OS-NAME] 사용법"을 입력하십시오! 작곡가를 설치하고 , 작곡가 설치를 참조하십시오.
- Symfony :
Symfony 2.8 (작곡가와 함께, 더 좋은 방법)을 설치해야하고, 터미널 (또는 Windows에서는 cmd)을 열고 웹 서버 경로로 가야합니다.
Symfony 2는 더 나은 구조 유형 중 하나 인 Bundles와 함께 작동합니다. 모두 Symfony의 번들입니다! 위에서 테스트 할 수 있습니다.
cd /your-web-server-path/
composer create-project symfony/framework-standard-edition example "2.8.*"
Symfony 2.8이 "example"디렉토리에 설치되었습니다.
- JMSSerializer 번들의 FOSRest (FriendsOfSymfony 용) :
다음 두 번들을 설치해야합니다.
JMSSerializer ( 설치 ) :
composer require jms/serializer-bundle "~0.13"
FosRestBundle ( 설치 ) :
composer require friendsofsymfony/rest-bundle
AppKernel.php에서 활성화하는 것을 잊지 마십시오!
- 기본 구성 :
자신의 "예제"번들을 만들고 데이터베이스를 만듭니다.
cd /path/to/your/symfony/
php app/console generate:bundle
php app/console doctrine:generate:database
Symfony 2.8 애플리케이션 구성 파일의 맨 아래로 이동하여 붙여 넣으십시오.
#app/config/config.yml
fos_rest:
format_listener:
rules:
- { path: '^/stackoverflower', priorities: ['xml', 'json'], fallback_format: xml, prefer_extension: true }
- { path: '^/', priorities: [ 'text/html', '*/*'], fallback_format: html, prefer_extension: true }
교리 디렉토리 ( "example / src / ExampleBundle / Entity")와 리소스 파일 ( "StackOverFlower.orm.yml")을 만드십시오 :
# src/ExampleBundle/Resources/config/doctrine/StackOverFlower.orm.yml
ExampleBundle\Entity\StackOverFlower:
type: entity
table: stackoverflower
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
name:
type: string
length: 100
엔티티 생성 및 스키마 업데이트 :
php app/console doctrine:generate:entity StackOverFlower
php app/console doctrine:schema:update --force
기본 컨트롤러 만들기 :
#src/ExampleBundle/Controller/StackOverFlowerController.php
namespace ExampleBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Delete;
use ExampleBundle\Entity\StackOverFlower;
class StackOverFlowerController extends FOSRestController
{
/**
* findStackOverFlowerByRequest
*
* @param Request $request
* @return StackOverFlower
* @throws NotFoundException
*/
private function findStackOverFlowerByRequest(Request $request) {
$id = $request->get('id');
$user = $this->getDoctrine()->getManager()->getRepository("ExampleBundle:StackOverFlower")->findOneBy(array('id' => $id));
return $user;
}
/**
* validateAndPersistEntity
*
* @param StackOverFlower $user
* @param Boolean $delete
* @return View the view
*/
private function validateAndPersistEntity(StackOverFlower $user, $delete = false) {
$template = "ExampleBundle:StackOverFlower:example.html.twig";
$validator = $this->get('validator');
$errors_list = $validator->validate($user);
if (count($errors_list) == 0) {
$em = $this->getDoctrine()->getManager();
if ($delete === true) {
$em->remove($user);
} else {
$em->persist($user);
}
$em->flush();
$view = $this->view($user)
->setTemplateVar('user')
->setTemplate($template);
} else {
$errors = "";
foreach ($errors_list as $error) {
$errors .= (string) $error->getMessage();
}
$view = $this->view($errors)
->setTemplateVar('errors')
->setTemplate($template);
}
return $view;
}
/**
* newStackOverFlowerAction
*
* @Get("/stackoverflower/new/{name}")
*
* @param Request $request
* @return String
*/
public function newStackOverFlowerAction(Request $request)
{
$user = new StackOverFlower();
$user->setName($request->get('name'));
$view = $this->validateAndPersistEntity($user);
return $this->handleView($view);
}
/**
* editStackOverFlowerAction
*
* @Get("/stackoverflower/edit/{id}/{name}")
*
* @param Request $request
* @return type
*/
public function editStackOverFlowerAction(Request $request) {
$user = $this->findStackOverFlowerByRequest($request);
if (! $user) {
$view = $this->view("No StackOverFlower found for this id:". $request->get('id'), 404);
return $this->handleView($view);
}
$user->setName($request->get('name'));
$view = $this->validateAndPersistEntity($user);
return $this->handleView($view);
}
/**
* deleteStackOverFlowerAction
*
* @Get("/stackoverflower/delete/{id}")
*
* @param Request $request
* @return type
*/
public function deleteStackOverFlowerAction(Request $request) {
$user = $this->findStackOverFlowerByRequest($request);
if (! $user) {
$view = $this->view("No StackOverFlower found for this id:". $request->get('id'), 404);
return $this->handleView();
}
$view = $this->validateAndPersistEntity($user, true);
return $this->handleView($view);
}
/**
* getStackOverFlowerAction
*
* @Get("/stackoverflowers")
*
* @param Request $request
* @return type
*/
public function getStackOverFlowerAction(Request $request) {
$template = "ExampleBundle:StackOverFlower:example.html.twig";
$users = $this->getDoctrine()->getManager()->getRepository("ExampleBundle:StackOverFlower")->findAll();
if (count($users) === 0) {
$view = $this->view("No StackOverFlower found.", 404);
return $this->handleView();
}
$view = $this->view($users)
->setTemplateVar('users')
->setTemplate($template);
return $this->handleView($view);
}
}
기본 나뭇 가지보기를 만듭니다.
#src/ExampleBundle/Resources/views/StackOverFlower.html.twig
{% if errors is defined %}
{{ errors }}
{% else %}
{% if users is defined %}
{{ users | serialize }}
{% else %}
{{ user | serialize }}
{% endif %}
{% endif %}
방금 첫 RESTFul API를 만들었습니다!
http : //your-server-name/your-symfony-path/app_dev.php/stackoverflower/new/test 에서 테스트 할 수 있습니다.
데이터베이스에서 볼 수 있듯이 "test"라는 이름으로 새 사용자가 생성되었습니다.
http : //your-server-name/your-symfony-path/app_dev.php/stackoverflowers 에서 stackoverflower의 목록을 가져올 수 있습니다 .
이 예제의 github 계정에 대한 전체 예제가 있습니다. Git Hub 예제 , "master"브랜치는이 예제, "real-routes"브랜치는 적절한 URL (예 : POST 및 DELETE) 예제입니다.
나중에 SOAP로 예제를 보자!
친애하는,
마티유
SOAP API 사용
SOAP (Simple Access Object Protocol)는 XML-RPC와 마찬가지로 XML 기반의 조상 이며, WSDL 이라는 파일이 있으며 노출 될 메소드를 설명합니다.
이 프로토콜은 종종 SOAP-Enveloppe , SOAP-Body 및 SOAP-Header를 기반으로 하며, 데이터는 구조에 포함되어 다른 언어에서 동일한 방식으로 해석됩니다.
자세한 내용은 다음을 참조하십시오. Wiki의 SOAP
위에서 설명한 것처럼 웹 서비스를 설명하는 데 가장 중요한 것은 WSDL 파일입니다. WSDL에 대한 설명
기본 작업은 SOAP API에 노출되는 것을 정의하는 것이며, 클래스는 비즈니스 프로세스가 기본 PHP SOAPServer 클래스에 의해 자동으로 처리됩니다. 당신은 여전히 코드가 필요합니다!
파일이 어떻게 생성되는지 보자.
- 서비스 : API URI와 관련 항목을 설정합니다.
- 바인딩 : 서비스와 관련된 작업을 정의합니다.
- 작업 : 웹에 공개 할 몇 가지 방법
- PortTypes : 쿼리 및 응답 정의
- 요청 및 응답 : 입력 및 출력 예상
- 메시지 : 각 IO에 대해 기대하는 formt (형식)은 단순 할 수 있습니다 (문자열, 정수, 부동 ...) 또는 복잡한 유형 (구조화 된 형식)
이 기본 정보를 사용하여 원하는 모든 API를 얻을 수 있습니다.
로컬 API에서 StackOverFlower (User)를 관리하기위한 SOAP API를 만들고 싶다고 가정 해보십시오.
예제를 만들어 보겠습니다!
웹 서버, Php cli, Composer, Symfony 2.8을 설치하고 새로운 번들 "ExampleBundle"을 만들고 위와 같이 스키마를 빌드하십시오.
우리가 비즈니스 로직을 구축하기 전에 우리는 컨트롤러를 노출 할 것을 알았습니다. 이 작업은 WSDL을 사용하여 수행됩니다. 다음은 WSDL의 좋은 구문 예입니다.
<definitions name="StackOverFlowerService"
targetNamespace="http://example/soap/stackoverflower.wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://example/soap/stackoverflower.wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<message name="NewRequest">
<part name="name" type="xsd:string"/>
</message>
<message name="NewResponse">
<part name="status" type="xsd:string"/>
</message>
<message name="getListRequest"></message>
<message name="getListResponse">
<part name="list" type="xsd:string"/>
</message>
<message name="editRequest">
<part name="id" type="xsd:string"/>
<part name="name" type="xsd:string"/>
</message>
<message name="editResponse">
<part name="status" type="xsd:string"/>
</message>
<message name="deleteRequest">
<part name="id" type="xsd:string"/>
</message>
<message name="deleteResponse">
<part name="status" type="xsd:string"/>
</message>
<portType name="StackOverFlower_PortType">
<operation name="newStack">
<input message="tns:NewRequest"/>
<output message="tns:NewResponse"/>
</operation>
<operation name="getList">
<input message="tns:getListRequest"/>
<output message="tns:getListResponse"/>
</operation>
<operation name="edit">
<input message="tns:editRequest"/>
<output message="tns:editResponse"/>
</operation>
<operation name="delete">
<input message="tns:deleteRequest"/>
<output message="tns:deleteResponse"/>
</operation>
</portType>
<binding name="StackOverFlower_Binding" type="tns:StackOverFlower_PortType">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="newStack">
<soap:operation soapAction="newStack"/>
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:example:new"
use="encoded"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:example:new"
use="encoded"/>
</output>
</operation>
<operation name="getList">
<soap:operation soapAction="getList"/>
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:example:get-list"
use="encoded"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:example:get-list"
use="encoded"/>
</output>
</operation>
<operation name="edit">
<soap:operation soapAction="edit"/>
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:example:edit"
use="encoded"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:example:edit"
use="encoded"/>
</output>
</operation>
<operation name="delete">
<soap:operation soapAction="delete"/>
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:example:delete"
use="encoded"/>
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:example:delete"
use="encoded"/>
</output>
</operation>
</binding>
<service name="StackOverFlower_Service">
<documentation>Description File of StackOverFlowerService</documentation>
<port binding="tns:StackOverFlower_Binding" name="StackOverFlower_Port">
<soap:address
location="http://example/stackoverflower/" />
</port>
</service>
</definitions>
우리는 이것을 symfony 디렉토리 (soap 서브 디렉토리에서 "stackoverflower.wsdl"이라고 부름)에서 가져와야합니다.
WSDl 예제 에서 실제로 영감을 얻었습니다. 온라인 WSDl Validator로 유효성을 검사 할 수 있습니다.
이 후 우리는 SOAP Symfony 2.8 Doc 에서 영감을 얻어 기본 서비스와 컨트롤러를 만들 수 있습니다.
PHP SOAPServer가 처리하는 서비스 :
#src\ExampleBundle\Services\StackOverFlowerService.php
namespace ExampleBundle\Services;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use ExampleBundle\Entity\StackOverFlower;
class StackOverFlowerService
{
private $em;
private $stackoverflower;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function newStack($name)
{
$stackoverflower = new StackOverFlower();
$stackoverflower->setName($name);
$this->em->persist($stackoverflower);
$this->em->flush();
return "ok";
}
public function getList()
{
$stackoverflowers = $this->em->getRepository("ExampleBundle:StackOverFlower")->findAll();
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new ObjectNormalizer());
$serializer = new Serializer($normalizers, $encoders);
return $serializer->serialize($stackoverflowers, 'json');
}
public function edit($id, $name)
{
$stackoverflower = $this->em->getRepository("ExampleBundle:StackOverFlower")->findOneById($id);
$stackoverflower->setName($name);
$this->em->persist($stackoverflower);
$this->em->flush();
return "ok";
}
public function delete($id)
{
$stackoverflower = $this->em->getRepository("ExampleBundle:StackOverFlower")->findOneById($id);
$this->em->remove($stackoverflower);
$this->em->flush();
return "ok";
}
}
이 서비스 구성 :
#src\ExampleBundle\Resources\config\services.yml
services:
stackoverflower_service:
class: ExampleBundle\Services\StackOverFlowerService
arguments: [@doctrine.orm.entity_manager]
보시다시피 Doctrine Entity Manger는 CRUD StackOverFlower Object에 사용해야하므로 종속 항목으로 주입합니다.
컨트롤러, 서비스 개체를 노출 :
#src\ExampleBundle\Controller\StackOverFlowerController.php
namespace ExampleBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class StackOverFlowerController extends Controller
{
public function indexAction()
{
ini_set("soap.wsdl_cache_enabled", "0");
$options = array(
'uri' => 'http://example/app_dev.php/soap',
'cache_wsdl' => WSDL_CACHE_NONE,
'exceptions' => true
);
$server = new \SoapServer(dirname(__FILE__).'/../../../**web/soap/stackoverflower.wsdl**', $options);
$server->setObject($this->get('stackoverflower_service'));
$response = new Response();
$response->headers->set('Content-Type', 'text/xml; charset=utf-8');
ob_start();
$server->handle();
$response->setContent(ob_get_clean());
return $response;
}
}
서비스에 대한 자세한 내용은 다음을 참조하십시오 : Symfony doc의 Service container
경로 :
example_soap:
path: /soap
defaults: { _controller: ExampleBundle:StackOverFlower:index }
기본 나뭇 가지 템플릿 :
#src\ExampleBundle\Resources\views\Soap\default.html.twig
{% if status is defined %}
{{ status }}
{% else %}
{{ list }}
{% endif %}
우리는 Symfony 2.8을 사용하여 첫 번째 SOAP API를 만들었습니다!
노출하기 전에 테스트해야합니다 !!
StackOverFlowerController에 다음을 추가합니다.
public function testNewAction(Request $request)
{
$service = $this->get('stackoverflower_service');
$result = $service->newStack($request->query->get('name'));
return $this->render('ExampleBundle:Soap:default.html.twig', array('status' => $result));
}
public function testEditAction(Request $request)
{
$service = $this->get('stackoverflower_service');
$result = $service->edit($request->query->get('id'), $request->query->get('name'));
return $this->render('ExampleBundle:Soap:default.html.twig', array('status' => $result));
}
public function testGetListAction(Request $request)
{
$service = $this->get('stackoverflower_service');
$result = $service->getList();
return $this->render('ExampleBundle:Soap:default.html.twig', array('list' => $result));
}
public function testDeleteAction(Request $request)
{
$service = $this->get('stackoverflower_service');
$result = $service->delete($request->query->get('id'));
return $this->render('ExampleBundle:Soap:default.html.twig', array('list' => $result));
}
// To test this from an another server, you can type this :
// $client = new \SoapClient("http://example/app_dev.php/soap?wsdl", array("trace" => 1, "exception" => 1));
// $result = $client->newStack($request->query->get('name'));
// print_r($result);
경로 :
test_new:
path: /stackoverflower/new
defaults: { _controller: ExampleBundle:StackOverFlower:testNew }
test_edit:
path: /stackoverflower/edit
defaults: { _controller: ExampleBundle:StackOverFlower:testEdit }
test_get_list:
path: /stackoverflower/get-list
defaults: { _controller: ExampleBundle:StackOverFlower:testGetList }
test_delete:
path: /stackoverflower/delete
defaults: { _controller: ExampleBundle:StackOverFlower:testDelete }
브라우저에 다음을 입력 할 수 있습니다.
이것은 SOAP이있는 비보안 API의 아주 기본적인 예입니다. 나중에 API 인증 뒤에 보안 된 예제를 사용할 수 있습니다.
그 모든 사람들 ...
마티유