Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write a wrapper to expose existing REST APIs as SOAP web services?

I have existing REST APIs, written using Django Rest Framework and now due to some client requirements I have to expose some of them as SOAP web services.

I want to know how to go about writing a wrapper in python so that I can expose some of my REST APIs as SOAP web services. OR should I make SOAP web services separately and reuse code ?

I know this is an odd situation but any help would be greatly appreciated.

like image 260
Ankur Sharma Avatar asked Jul 24 '17 11:07

Ankur Sharma


People also ask

Can SOAP service use RESTful web services?

SOAP can't use REST because it is a protocol. REST can use SOAP web services because it is a concept and can use any protocol like HTTP, SOAP.

Can we call a SOAP API from REST API?

Instead of an API reference, which gives you the Request and Response formats and requirements, SOAP publishes a WSDL. So if you've got one of these SOAP Services which breaks standards, if you can get the text of a successful Request, you can use REST to make the call with that request body.

How do I convert a SOAP Web service to a REST API?

Since API Builder APIs are always REST APIs, all we need to do to convert a SOAP service to a REST API is the following: Create the XML body from the REST parameter(s) Make a web service call to the SOAP service. Convert the SOAP XML response to a REST/JSON response.


Video Answer


1 Answers

You can say, SOAP and REST are basically apples and oranges.

You basically need something, where you can consume the REST API's.

As I see, you have some options:

  • Use a SOAP service separately running on another port (endpoint). For that I would say, use framework's like Spyne check out sample hello world
  • Use the clients preferred way, either SOAP via WSGI or SOAP via HttpRPC
  • Invoke the same REST API endpoints which you created via the methods in SOAP. We had used an internal api wrapper in one of application, which is as:
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)

How you can use this?

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:{0}{1}'.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())

Now there are some of examples which you can look into, being the Django configuration for making it available

like image 181
Nagaraj Tantri Avatar answered Oct 21 '22 11:10

Nagaraj Tantri