编写一个包装器将现有的 REST API 公开为 SOAP Web 服务?

Posted

技术标签:

【中文标题】编写一个包装器将现有的 REST API 公开为 SOAP Web 服务?【英文标题】:Write a wrapper to expose existing REST APIs as SOAP web services? 【发布时间】:2017-12-29 22:54:23 【问题描述】:

我有现有的 REST API,使用 Django Rest Framework 编写,现在由于一些客户端要求,我必须将其中一些公开为 SOAP Web 服务。

我想知道如何在 python 中编写一个包装器,以便我可以将我的一些 REST API 公开为 SOAP Web 服务。或者我应该单独制作 SOAP Web 服务并重用代码?

我知道这是一种奇怪的情况,但我们将不胜感激。

【问题讨论】:

然后?你的问题到底是什么? 我想知道如何在 python 中编写一个包装器,以便我可以将我的一些 REST API 公开为 SOAP Web 服务。或者我应该单独制作 SOAP Web 服务并重用代码? 那么你尝试了什么? 目前我正在评估这两个选项。我更倾向于编写单独的 SOAP Web 服务,然后重用内部代码。但问题是,将来我可能不得不以 SOAP Web 服务的形式公开更多这些 API,所以我认为也许可以使用某种包装器将这些 API 公开为 SOAP Web 服务和 REST API。 【参考方案1】:

你可以说SOAPREST基本上是applesoranges

您基本上需要一些可以使用 REST API 的东西。

如我所见,您有一些选择:

使用在另一个端口(端点)上单独运行的 SOAP 服务。为此我想说,使用类似Spyne的框架查看示例hello world 使用客户端首选方式,通过 WSGI 的 SOAP 或通过 HttpRPC 的 SOAP 调用您通过 SOAP 中的方法创建的相同 REST API 端点。 我们在其中一个应用程序中使用了内部 api 包装器,如下所示:
def wrap_internal_api_call(requests_api_method, uri, 
                           data, cookies=None, headers=None):

    return requests_api_method(uri, data=data, files=files, 
               cookies=cookies, headers=headers)

如何使用它?

import requests

from django.core.urlresolvers import reverse
from django.conf import settings

from spyne.service import Service
from spyne.decorator import srpc
from spyne.model import ByteArray, DateTime, Uuid, String, Integer, Integer8, \
    ComplexModel, Array


# This method will hit the internal API which is written in DJANGO REST FRAMEWORK
def build_internal_uri(uri):
  return 'http://localhost:01'.format(settings.INTERNAL_API_PORT, uri)


class RequestHeader(ComplexModel):
  some_field = String


class SomeService(Service):
    # Headers related doc
    # https://github.com/arskom/spyne/blob/68b9d5feb71b169f07180aaecfbe843d8ba500bf/doc/source/manual/06_metadata.rst#protocol-headers 
    __in_header__ = RequestHeader

  @srpc(String, _returns=String)
  def echo_string(s):
    headers = ctx.in_header.some_field

    # Reverse url from the urls.py file
    local_order_fetch_url = build_internal_uri(reverse('website:order_details')) + '?order_id=' + order_id

    response = wrap_internal_api_call(requests.get, local_order_fetch_url, 
             'data': 'sample_data' , None, headers)

    return response['data'] # Some string data


app = Application([SomeService], 'tns', in_protocol=HttpRpc(parse_cookie=True), 
                out_protocol=HttpRpc())

现在您可以查看一些示例,例如 Django 配置以使其成为 available

【讨论】:

【参考方案2】:

让我们讨论这两种方法及其优缺点

单独的 SOAP 服务

重用相同的代码 - 如果您确定代码更改不会影响两个代码流,那么可以这样做。 功能扩展 - 如果您确定新功能扩展不会影响其他部分,那么最好还是继续。 可扩展性 - 如果新 API 是同一个应用程序的一部分,并且您确信它可以通过更多负载进行扩展,那么这又是一个不错的选择。 扩展 - 如果您确定将来添加更多 API 不会造成代码混乱,那么还是可以选择。

Soap Wrapper Using Python(我最喜欢和建议的方式)

关注点分离 有了这个,您可以确保您编写的任何代码都与主逻辑分开,您可以轻松插入和插入新事物。

如果出现这种情况,请回答上述所有问题。

您的电话,

欢迎评论和批评

【讨论】:

投反对票前请告诉我原因

以上是关于编写一个包装器将现有的 REST API 公开为 SOAP Web 服务?的主要内容,如果未能解决你的问题,请参考以下文章

如何将现有的回调 API 转换为 Promise?

如何将现有的回调 API 转换为 Promise?

如何将现有的回调 API 转换为 Promise?

如何将现有的回调 API 转换为 Promise?

如何将现有的回调 API 转换为 Promise?

将现有的 Spring 应用程序转换为 Spring-Boot