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
- 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 filemethod
- defines the http method used, here, it's POSTpostbody
- 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 needstransforms
- 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.
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" } } } } }