Making a simple stubserver with Drakov
Today I'll show how you can create a simple stubserver with Drakov. If you do some frontend programming, you've probably already installed npm (Node Package Manager), otherwise here is how you install that. Then with npm you can install Drakov.
$ sudo npm install -g drakov
We can specify in a markdown file how the stubserver will behave. Using the rules of api-blueprint. This is normally used to specify what your API will look like and what inputs/outputs there are. Here we use it to actually create these in and outputs. First let start with some GETs. 1-get.md
FORMAT: 1A
Vegetable API stub
gets
Root [/]
Documentation [GET]
- Response 200 (text/plain) This is an API about vegetables. With examples about how to get them.
Vegetables [/vegetables]
Get all vegetables [GET]
- Response 200 (application/json) [ { "name": "eggplant", "color": "purple" }, { "name": "broccoli", "color": "green" } ]
one vegetable [/vegetables/{name}]
Get one vegetable [GET]
- Response 200 (application/json) { "name": "eggplant", "color": "purple" }
After the ## we specify the paths. Underneath that we specify different methods (POST,GET). And how we will respond. So here we have 3 endpoints. On root (/) we return some documentation in text format. On /vegetables we return a list of vegetables. And specific vegetables under /vegetables/xxx We can start Drakov with this specification:
$ drakov -f 1-get.md
Now we can try some requests with curl:
$ curl localhost:3000/ This is an API about vegetables. With examples about how to get them.
$ curl localhost:3000/vegetables [ { "name": "eggplant", "color": "purple" }, { "name": "broccoli", "color": "green" } ]
$ curl localhost:3000/vegetables/carrot { "name": "eggplant", "color": "purple" }
$ curl localhost:3000/typo Cannot GET /typo
Lets try some POSTs now. 2-post.md:
FORMAT: 1A
Vegetable API stub
Here we accept any JSON object for the POST
Vegetables [/vegetables]
add a vegetable [POST]
- Request (application/json)
- Attributes (object)
- Response 201
A nice extra because it's a markdown file is that we can also let Markdown format it to make it even more readable. See 2-post.md Here we made it so that you can post any JSON object to /vegetables and return with http code 201 (created).
$ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '{"name": "eggplant", "color": "purple"}' $ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '{"bla": "bla"}'
We say it needs to be JSON, so it will not work without the Content-Type header
$ curl -X POST localhost:3000/vegetables -d '{"name": "eggplant", "color": "purple"}' Cannot POST /vegetables
It will also not work with incorrect JSON (no quotes around eggplant)
$ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '{"name": eggplant, "color": "purple"}' Cannot POST /vegetables
It will also not work with JSON that is not an object
$ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '[]' Cannot POST /vegetables $ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '"bla"' Cannot POST /vegetables
We can also define some data structures to parse input. 3-dataStructures.md:
FORMAT: 1A
Vegetable API stub
data structures
Data Structures
Vegetable
- name: eggplant (string, required)
- color: purple (string)
Vegetables [/vegetables]
Get all vegetables [GET]
- Response 200 (application/json)
- Attributes (array[Vegetable])
add a vegetable [POST]
- Request (application/json)
- Attributes (Vegetable)
- Response 201
one vegetable [/vegetables/{name}]
Get one vegetable [GET]
- Response 200 (application/json)
- Attributes (Vegetable)
Show a list (of one object) with the example object.
$ curl localhost:3000/vegetables [ { "name": "eggplant", "color": "purple" } ]
Shows the example object
$ curl localhost:3000/vegetables/carrot { "name": "eggplant", "color": "purple" }
The input will need to be a correct JSON object
$ curl -X POST localhost:3000/vegetables -d '{"name": "eggplant", "color": "purple"}' Cannot POST /vegetables $ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '{"name": eggplant, "color": "purple"}' Cannot POST /vegetables $ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '[]' Cannot POST /vegetables $ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '"bla"' Cannot POST /vegetables
Now it will fail on a JSON object that is not to our specifications
$ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '{"bla": "bla"}' Cannot POST /vegetables $ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '{"name": "eggplant", "color": 2}' Cannot POST /vegetables
It will work with a correct vegetable
$ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '{"name": "eggplant", "color": "purple"}' $ curl -X POST localhost:3000/vegetables -H "Content-Type: application/json" -d '{"name": "pepper"}'
These examples are also available on https://github.com/tammosminia/blog-drakov