Making a simple stubserver with Drakov

Tammo

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

AngularConnect 2016 conference report episode 1 Caching HTTP requests in AngularJS