サーチ…
RESTFul APIを使用する
REP(Representational State Transfer)は、Roy Fieldingが2000年に導入し定義したWeb開発に使用されるアーキテクチャスタイルです。
wikiで見る: REST wiki
HTTPプロトコル( Wiki上のHTTP)、HTTP要求(GET、POST、PATCH、DELETE ...)/応答コード(404,400,200,201,500 ...)およびボディ構造に基づいています。
これはあなたのデータをインターネット上の別のシステムに公開するのに最適です。
あなたのローカルデータベース上でStackOverFlower(User)を管理するためのRESTFul APIを作成したいとします。
例を作ろう!
Symfony 2.8フレームワーク
- Webサーバー:
ローカルマシンにWebサーバーをインストールして構成する必要があります.WampまたはLampまたはMampを参照してください。最新バージョンのPHPが必要です ( Symfonyの要件!!! )
- Php cliと作曲家:
あなたは私たちの友人のGoogleでこの "PHP cli [OS-NAME] how-to"をタイプして、PHP cli(システムによって異なる)を設定しなければなりません!あなたはコンポーザをインストールする必要があります。
- Symfony:
Symfony 2.8をインストールする必要があります(コンポーザー付き、より良い方法です)。端末(またはWindowsのcmd)を開き、Webサーバーのパスに移動します。
Symfony 2はより良い構造体型の一つであるバンドルと連携します。すべてはSymfonyのバンドルです!上記のテストができます。
cd /your-web-server-path/
composer create-project symfony/framework-standard-edition example "2.8.*"
Symfony 2.8が "example"ディレクトリにインストールされています。
- JMSSerializerバンドルのFOSRest(FriendsOfSymfony用):
次の2つのバンドルをインストールする必要があります。
JMSSerializer( インストール ):
composer require jms/serializer-bundle "~0.13"
FosRestBundle( インストール ):
composer require friendsofsymfony/rest-bundle
AppKernel.phpでそれらを有効にすることを忘れないでください!
- 基本設定:
独自の "Example"バンドルを作成し、データベースを作成します。
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 }
doctrineディレクトリ( "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);
}
}
デフォルトのTwigビューを作成する:
#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"という名前の新しいユーザーが作成されました。
stackoverflowerのリストは、 http://your-server-name/your-symfony-path/app_dev.php/stackoverflowersで取得できます。
この例の私のgithubアカウントの完全な例があります: Git Hubの例 、この例の "master"ブランチ、さらに "real-routes"ブランチの例(POSTやDELETEなど)
後でSOAPで例を見てください!
宜しくお願いします、
マチュー
SOAP APIを使用する
SOAP(Simple Access Object Protocol)はXML-RPCのようにXMLベースのもので、 祖先であり 、公開されるメソッドを記述するWSDLというファイルがあります。
このプロトコルは、多くの場合SOAP-Enveloppe 、 SOAP-Body 、およびSOAP-Headerに基づいています。データは構造内にエンベロープされ、異なる言語から同じ方法で解釈されます。
詳細は、以下を参照してください: SOAP on wiki
上で説明したように、Webサービスを記述するために最も重要なのはWSDLファイルです。以下を参照してください。WSDL on wiki
この作業の基本は、SOAP APIに公開されているものを定義することです。クラスとビジネスプロセスは、基本的なPHP SOAPServerクラスによって自動的に処理されます。あなたはまだコードが必要です!
ファイルの構築方法を見てみましょう:
- サービス:API URIと関連するものを設定します。
- バインディング:サービスに関連する操作を定義します。
- 操作:Webに公開するいくつかのメソッド
- PortTypes:クエリと応答を定義する
- リクエストとレスポンス:入力と出力を期待するもの
- メッセージ:各IO上でどのようなformt(パラメータ)が必要なのかは、単純なもの(文字列、整数、浮動小数点数)または複合型(構造化形式)
この基本情報を使用すると、必要なすべてのAPIを実現できます。
あなたのローカルデータベース上であなたのStackOverFlower(User)を管理するSOAP APIを作ろうとしているとします。
例を作ろう!
Webサーバー、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>
これをあなたのweb symfonyディレクトリ(soapサブディレクトリにあり、これを "stackoverflower.wsdl"と名づけてください)で取得する必要があります。
本当にWSD1の例から触発されました 。 オンラインWSDl検証ツールで検証することができます
その後、 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のサービスコンテナ
ルート :
example_soap:
path: /soap
defaults: { _controller: ExampleBundle:StackOverFlower:index }
基本的なTwigテンプレート:
#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のキー認証の背後にある安全な例の例を行うことができます。
そのすべての人々...
マチュー