Routes¶
The routes
argument must be a dictionary containing defined routes per
vroot.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import zunzuncito
root = 'my_api'
versions = ['v0', 'v1']
hosts = {
'*': 'default',
'domain.tld': 'default',
'*.domain.tld': 'default',
'beta.domain.tld': 'beta'
}
routes = {'default':[
('/(md5|sha1|sha256|sha512)(/.*)?', 'hasher', 'GET, POST')
],'beta':[
('/upload/?.*', 'upload', 'PUT, POST'),
('/.*', 'default')
]}
app = zunzuncito.ZunZun(root, versions, hosts, routes, debug=True)
|
Note
By default, if no routes specified, the requests are handled by matching the URI request with an valid API Resource, you only need to specify routes if want to handle different URI requests with a single API Resource
Example¶
The request:
http://api.zunzun.io/v0/env
Will be handled by the python custom module zun_env/zun_env.py
But all the following GET requests:
- http://api.zunzun.io/v0/md5/freebsd
- http://api.zunzun.io/v0/sha1/freebsd
- http://api.zunzun.io/v0/sha256/freebsd
- http://api.zunzun.io/v0/sha512/freebsd
And also this POST requests:
curl -i -X POST http://api.zunzun.io/v0/md5 -d 'freebsd'
curl -i -X POST http://api.zunzun.io/v0/sha1 -d 'freebsd'
curl -i -X POST http://api.zunzun.io/v0/sha256 -d 'freebsd'
curl -i -X POST http://api.zunzun.io/v0/sha512 -d 'freebsd'
Will be handled by the pythom custom module zun_hasher/zun_hahser.py, this is because a specified route:
('/(md5|sha1|sha256|sha512)(/.*)?', 'hasher', 'GET, POST')
You can totally omit routes and handle all by following the API directory structure, this can give you more fine control over you API, for example in the previous example you could create modules for every hash algorithm, and have independent modules like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | `--v0
|--__init__.py
|--zun_md5
| |--__init__.py
| `--zun_md5.py
|--zun_sha1
| |--__init__.py
| `--zun_sha1.py
|--zun_sha256
| |--__init__.py
| `--zun_sha256.py
`--zun_sha512
|--__init__.py
`--zun_sha512.py
|
Note
Defining routes or using the directory structure is a design choice, some times having all in one module can be easy to maintain, while other times having a module for each specific task, would be prefered.
See also
The zun_ prefix
The flow¶
When a new request arrive, the ZunZun router searches for a vroot
declared on
the hosts dictionary matching the current HTTP_HOST.
Once a vroot
is found, the ZunZun router parses the REQUEST_URI in order to
accomplish this pattern:
/version/api_resource/path
The router first analyses the URI and determines if it is versioned or not by
finding a match with the current specified versions
in case no one is found, fallback to the default which is always the first
item on the versions list in case one provided, or v0
.
After this process, the REQUEST_URI becomes a list of resources - something like:
['version', 'api_resource', 'path']
# for http://api.zunzun.io/v0/env
['v0', 'env']
# for http://api.zunzun.io/v0/sha256/freebsd
['v0', 'sha256', 'freebsd']
The second step on the router is to find a match within the routes
dictionary and the
local modules.
In case a list of routes
is passed as an argument to the ZunZun instance, the
router will try to match the API_resource with the items of the routes
dictionary. If no matches are found it will try to find the module in the root directory.
Routes dictionary structure¶
In the above example, the routes
dictionary contains:
vroot | regular expression | API Resource | HTTP methods |
---|---|---|---|
default | /(md5|sha1|sha256|sha512)(/.*)? | hasher | ‘GET, POST’ |
beta | /upload/?.* | upload | ‘PUT, POST’ |
beta | /.* | default |
Translating the table to code:
1 2 3 4 5 6 7 8 | routes = {}
routes['default'] = [
('/(md5|sha1|sha256|sha512)(/.*)?', 'hasher', 'GET, POST')
]
routes['beta'] = [
('/upload/?.*', 'upload', 'PUT, POST'),
('/.*', 'default')
]
|
Warning
Regular expressions have priority, for example the regex (/.*)
will catch-all the request, that’s why in our example is the
last regex, since order is important.
Directory structure¶
The API directory structure for the examples presented here is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /home/
`--zunzun/
|--app.py
`--my_api
|--__init__.py
|--default
| |--__init__.py
| |--v0
| | |--__init__.py
| | |--zun_default
| | | |--__init__.py
| | | `--zun_default.py
| | |--zun_env
| | | |--__init__.py
| | | `--zun_env.py
| | `--zun_hasher
| | |--__init__.py
| | `--zun_hasher.py
| `--v1
| |--__init__.py
| |--zun_default
| | |--__init__.py
| | `--zun_default.py
| `--zun_hasher
| |--__init__.py
| `--zun_hasher.py
`--beta
|--__init__.py
`--v0
|--__init__.py
|--zun_default
| |--__init__.py
| `--zun_default.py
`--zun_upload
|--__init__.py
`--zun_upload.py
|
A great amount of time has been spent creating, crafting and maintaining this software, please consider donating.
Donating helps ensure continued support, development and availability.
comments powered by Disqus