Making a simple stubserver with Drakov

by Tammo — 5 minutes

Today I'll show how you can create a simple stubserver with Drakov. If you do some front-end 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

````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:

```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:

```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

meerdivotion

Cases

Blogs

Event