StepZen is now part of IBM. For the most recent product information and updates go to
https://www.ibm.com/products/stepzen

Getting Started with SOAP

Create a GraphQL API for SOAP backends in minutes

StepZen's custom directive @rest extends to SOAP services through postbody configuration. In this way, StepZen supports both REST structures and SOAP protocols. SOAP services vary a lot. Use this tutorial to learn how to use StepZen to create a temperature converter so you can apply your knowledge to other SOAP services.

Create Your Schema

  1. Create a file index.graphql and add the following code in it:
	type Query {
    conversion (celsius: Float): JSON
        @rest (
            endpoint: "https://www.w3schools.com/xml/tempconvert.asmx", 
            method: POST,
            postbody: """
                <?xml version="1.0" encoding="utf-8"?>
                <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  	            <soap12:Body>
                <CelsiusToFahrenheit xmlns="https://www.w3schools.com/xml/">
                <Celsius>{{ .Get "celsius" }}</Celsius>
                </CelsiusToFahrenheit>
  	            </soap12:Body>
                </soap12:Envelope>
                                  """
            headers: [{name:"Content-Type", value: "text/xml"},
                      {name: "Content-Type", value: "charset=utf-8"}]
            transforms: [{pathpattern: "[]", editor:"xml2json"}]
    )
}

We are telling StepZen to make the SOAP call using the custom @rest directive. @rest's arguments include endpoint, method, postbody, headers, and transforms.

  • endpoint - connects the StepZen GraphQL API to the ASP.NET Web Service file
  • method - defines the http method used, here, it's POST
  • postbody - defines the POST body, you can see how to pass a GraphQL argument into the body of the SOAP message with {{ .Get "celsius" }}
  • headers - adds appropriate headers; check with your own SOAP backend on what headers it needs
  • transforms - transforms the response from XML to JSON using an editor xml2json (the pathpattern is always "[]" for xml2json)

Deploy Your API

Run stepzen start inside your workspace, and pick an api name.

stepzen start
? What would you like your endpoint to be called? (api/prodding-seastar) 

You'll get a message in your terminal confirming successful deployment.

To test, run a curl command similar to the following.

curl "https://<your-account-name>.stepzen.net/api/prodding-seastar/__graphql" --header "Authorization: Apikey $(stepzen whoami --apikey)" --header "Content-Type: application/json" --data '{"query": "{conversion (celsius: 20.0)}"}’ 

You will get a JSON response from your SOAP service with the CelsiusToFahrenheitResult result.

{
	"data": {
		"conversion": {
			"Envelope": {
				"Body": {
					"CelsiusToFahrenheitResponse": {
						"CelsiusToFahrenheitResult": "68",
						"xmlns": "https://www.w3schools.com/xml/"
					}
				},
				"soap": "http://www.w3.org/2003/05/soap-envelope",
				"xsd": "http://www.w3.org/2001/XMLSchema",
				"xsi": "http://www.w3.org/2001/XMLSchema-instance"
			}
		}
	}
}                     

Create GraphQL Types With JSON2SDL

At this point, the entire JSON body comes back. To allow the API user to specify which pieces of data are returned from the query, you will need to add GraphQL types that reflect the structure of the SOAP service. You can manually create GraphQL types, or you can use StepZen's JSON2SDL tool to transform the response into the correct SDL (Schema Definition Language).

To do that, take the above JSON response and paste it on the left side of JSON2SDL. Hit run, and copy the generated SDL into the bottom of your index.graphql file.

image JSON2SDL gif

Modify your type Query in your index.graphql file to return Envelope as opposed to JSON for the query.

    ~~conversion (celsius: Float): JSON~~
    conversion (celsius: Float): Envelope

Next, add a resultroot: "Envelope" argument below your transforms argument. This header specifies the path that StepZen is to use as the root. Your index.graphql should look like:

type Query {
    conversion (celsius: Float): Envelope
    @rest (endpoint: "https://www.w3schools.com/xml/tempconvert.asmx",
    method: POST,
    postbody: """
    <?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <CelsiusToFahrenheit xmlns="https://www.w3schools.com/xml/">
      <Celsius>{{ .Get "celsius" }}</Celsius>
    </CelsiusToFahrenheit>
  </soap12:Body>
</soap12:Envelope>
    """
    headers: [{name:"Content-Type", value: "text/xml"},
    {name: "Content-Type", value: "charset=utf-8"}],
    transforms: [{pathpattern: "[]", editor:"xml2json"}]
    resultroot: Envelope
    )
}
type CelsiusToFahrenheitResponse {
  CelsiusToFahrenheitResult: String
  xmlns: String
}
type Body {
  CelsiusToFahrenheitResponse: CelsiusToFahrenheitResponse
}
type Envelope {
  Body: Body
  soap: String
  xsd: String
  xsi: String
}
type Conversion {
  Envelope: Envelope
}
type Data {
  conversion: Conversion
}
type Root {
  data: Data
}

Run stepzen start once more, then run a curl command to verify your updated response.

curl "https://public3cad390d353e929b.stepzen.net/api/prodding-seastar/__graphql" --header "Authorization: Apikey $(stepzen whoami --apikey)" --header "Content-Type: application/json" --data '{"query": "{conversion (celsius: 20.0){Body {CelsiusToFahrenheitResponse {CelsiusToFahrenheitResult}}}}"}'

You now have a GraphQL endpoint where you can select any field from the XML response via your GraphQL request.

{
	"data": {
		"conversion": {
			"Body": {
				"CelsiusToFahrenheitResponse": {
					"CelsiusToFahrenheitResult": "68"
				}
			}
		}
	}
}