宁静和肥皂

时间:2009-08-25 08:55:47

标签: rest soap

如何同时实现restful和SOAP?

6 个答案:

答案 0 :(得分:12)

您无法实现符合REST和SOAP的单个API。

但是,可以创建一个公开RESTful API和具有同等功能的SOAP API的系统。

为了做到这一点,系统的底层实现应该独立于两个API。例如,如果您使用Java实现系统,则底层实现和每个API都应该位于独立的包中。如果是Python,独立模块。等

理想情况下,如果你有无限的时间,每个API都将完全设计为符合其架构风格的基础范例:RESTful API将适当地围绕资源和状态表示的转移,而SOAP API将适当地围绕程序及其参数和返回值。

但是,为了节省一些时间,可以通过简单地将资源名称与HTTP方法相结合,在REST API之后建模SOAP API。结果是一种REST-via-SOAP混合。

例如,如果您的REST API具有名为Mailboxes的资源,该资源支持GET,POST,PUT和DELETE,并接受并返回类型为application/json的表示,则可以对资源进行建模,它的方法是创建以下SOAP方法:

  • get_mailboxes(url, options) returns jsonDoc
  • post_mailboxes(url, options, jsonDoc) returns jsonDoc
  • put_mailboxes(url, options, jsonDoc) returns jsonDoc
  • delete_mailboxes(url, options) returns nothing

如果我的符号不正确,我道歉,我对SOAP并不熟悉。

答案 1 :(得分:2)

您可以公开与基于SOAP和RESTful相同的服务。带有WSDL 2.0的Axis2支持此功能。

请参阅此文RESTful Web Services with Apache Axis2 - 详细解释..

谢谢..

答案 2 :(得分:1)

REST和SOAP是互斥的概念。你不能。

答案 3 :(得分:1)

给定一个任意服务,没有什么能阻止你向它暴露REST和SOAP接口。但是,服务的性质可能会使一种访问方法比另一种更方便。

答案 4 :(得分:1)

首先使用所有元数据注释制作肥皂服务 确保你的@webserivce

中有一个wsdlLocation

然后您可以添加所有剩余的注释和休息类 这将在同一个代理

中工作

答案 5 :(得分:0)

基本上你可以采用这种方法。实际上我已经使用zend框架在php中实现了。

您可以创建一个类,其中包含您希望通过rest或soap公开的所有api函数。然后你可以创建一个php脚本来获取请求,并根据客户端发送的参数处理请求并将其发送给soap或rest服务。看看这段代码。

我有这个功能来检查从客户端传入的参数,如果是休息然后将请求分派给其余服务,否则,如果参数是soap然后将请求分派给soap服务,但请注意Zend_Rest_Server和Zend_Soap_Server类配置为使用相同的类($ controllerClassName)来处理请求。

所以使用rest和soap暴露相同的api(功能)。

public function dispatch()
{

    $this->preDispatch();

    $include_file_path = sprintf(APPLICATION_PATH . "/modules/%s/controllers/%s.php", ucfirst($this->request->getModuleName()), ucfirst($this->request->getControllerName()));
    require_once $include_file_path;

    $controllerClassName = sprintf("%s_Controller", ucfirst($this->request->getControllerName()));

    switch (strtolower($this->request->getServiceType())) {
        case self::REST_SERVICE:
            $r = $this->getRequest();
            $server = new Rest_Server();
            $server->setClass($controllerClassName);
            $server->handleRequest($this->request);

            break;

        case self::SOAP_SERVICE:

            if (array_key_exists('wsdl', $this->getRequest()->getQuery()) || array_key_exists('WSDL', $this->getRequest()->getQuery())) {

                $auto = new Zend_Soap_AutoDiscover();
                $auto->setClass($controllerClassName);
                $auto->handle();
            } elseif (count($this->getRequest()->getQuery()) == 0) {

                $wsdl = sprintf('http://%s%s?wsdl', $this->getRequest()->getHttpHost(), $this->getRequest()->getPathInfo());

                $soapServer = new Soap_Server($wsdl);
                $soapServer->setClass($controllerClassName);
                $soapServer->handle();
            }

            break;

        default:
            break;
    }

    $this->postDispatch();
}