This post builds on what we’ve learned already to create a working Swagger front-end that talks to a real server. (See Testing Swagger and Making Swagger work for real, part 1)
The previous example used generated server code for the back end so it worked nicely with the Swagger UI front end by design. The next step is to make it work with a real Zulip server, which does not.
For the codegen-based test, a curl command to create a new item looked like this:
curl -X POST --header 'Content-Type: application/json'
--header 'Accept: application/json'
-d '{ "id": 5, "name": "potato" }'
'http://10.2.3.4:8080/api/items'
But creating a new message in Zulip looks like this:
curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json' --header 'Authorization: Basic MyAuthHash' -d 'type=stream&content=bar&to=test&subject=foo' 'http://10.2.3.4:9991/api/v1/messages'
There are two differences to account for here. The first is that the Zulip endpoint is expecting url-encoded text, not JSON, in the POST data. The second is that it requires authentication. Both of these need to be correctly described in the YAML description of the API.
Building the YAML file
The store example specified that the endpoint both accepts and produces “application/json” data:
consumes: - application/json produces: - application/json
and “in: body” in the parameter list means it expects them to be in the body of the POST in the format described by the newItem schema.
post:
description: Creates a new item in the store. Duplicates are allowed
operationId: addItem
produces:
- application/json
parameters:
- name: item
in: body
description: Item to add to the store
required: true
schema:
$ref: '#/definitions/newItem'
For Zulip, the endpoint still returns JSON, but is expecting to receive x-www-form-urlencoded data (just like an HTML form.)
consumes: - application/x-www-form-urlencoded produces: - application/json
The individual parameters must be defined as “formData”, which doesn’t use a separate schema definition:
parameters:
- name: type
in: formData
description: type of message to create
required: true
type: string
- name: content
in: formData
description: content of message to create
required: true
type: string
- name: to
in: formData
description: recipient of message to create
required: true
type: string
- name: subject
in: formData
description: subject of message to create
required: true
type: string
Now that the incoming data is defined, we need to make it use Basic Auth to authenticate with the Zulip back end. The first part of that is to add a “securityDefinitions” section:
securityDefinitions:
basicAuth:
type: basic
description: HTTP Basic Auth
and in the parameters specify that they require this security:
security: - basicAuth: []
Here’s the full YAML file:
swagger: '2.0'
info:
version: '1.0.0'
title: Sample API
description: Some Stuff I wrote
termsOfService: http://example.com
contact:
name: Feorlen
email: nobody@example.com
url: http://example.com
license:
name: Foo
url: http://example.com
host: 10.2.3.4:9991
basePath: /api/v1
schemes:
- http
consumes:
- application/x-www-form-urlencoded
produces:
- application/json
securityDefinitions:
basicAuth:
type: basic
description: HTTP Basic Auth
paths:
/messages:
post:
description: Creates a new Zulip message
operationId: addMessage
produces:
- application/json
parameters:
- name: type
in: formData
description: type of message to create
required: true
type: string
- name: content
in: formData
description: content of message to create
required: true
type: string
- name: to
in: formData
description: recipient of message to create
required: true
type: string
- name: subject
in: formData
description: subject of message to create
required: true
type: string
security:
- basicAuth: []
responses:
'200':
description: message response
schema:
$ref: '#/definitions/messageResponse'
default:
description: unexpected error
schema:
$ref: '#/definitions/errorModel'
definitions:
messageResponse:
type: object
required:
- msg
- result
- id
properties:
msg:
type: string
result:
type: string
id:
type: string
errorModel:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
With this configuration, Swagger UI generates a curl command that can connect to the server, authenticate, and create a new post. The problem is, however, that the nice clickable demo that Swagger UI offers doesn’t.
I’ll get into that with the next post.
Leave a Reply