Module: TLAW::DSL
- Defined in:
- lib/tlaw/dsl.rb
Overview
This module is core of a TLAW API definition. It works like this:
class MyAPI < TLAW::API
define do # here starts what DSL does
namespace :ns do
endpoint :es do
param :param1, Integer, default: 1
end
end
end
end
Methods of current namespace documentation describe everything you
can use inside define
blocks. Actual structure of things is a bit
more complicated (relate to lib/tlaw/dsl.rb if you wish), but current
documentation structure considered to be most informative.
Instance Method Summary collapse
-
#base(url) ⇒ Object
Allows to set entire API base URL, all endpoints and namespaces pathes are calculated relative to it.
-
#desc(text) ⇒ Object
Allows to set description string for your API object.
-
#docs(link) ⇒ Object
Allows to add link to documentation as a separate line to object description.
-
#endpoint(name, path = nil, **opts, &block) ⇒ Object
Defines new endpoint or updates existing one.
-
#namespace(name, path = nil, &block) ⇒ Object
Defines new namespace or updates existing one.
-
#param(name, type = nil, keyword: true, required: false, **opts) ⇒ Object
Defines parameter for current API (global), namespace or endpoint.
-
#post_process(key = nil, &block) ⇒ Object
Sets post-processors for response.
-
#post_process_items(key, &block) ⇒ Object
Sets post-processors for each items of array, being at
key
(if the key is present in response, and if its value is array of hashes). -
#post_process_replace(&block) ⇒ Object
Just like #post_process for entire response, but replaces it with what block returns.
Instance Method Details
#base(url) ⇒ Object
Allows to set entire API base URL, all endpoints and namespaces pathes are calculated relative to it.
Works for: API
|
# File 'lib/tlaw/dsl.rb', line 23
|
#desc(text) ⇒ Object
Allows to set description string for your API object. It can be multiline, and TLAW will automatically un-indent excessive indentations:
# ...several levels of indents while you create a definition
desc %Q{
This is some endpoint.
And it works!
}
# ...but when you are using it...
p my_api.endpoints[:endpoint].describe
# This is some endpoint.
# And it works!
# ....
Works for: API, namespace, endpoint
|
# File 'lib/tlaw/dsl.rb', line 31
|
#docs(link) ⇒ Object
Allows to add link to documentation as a separate line to object description. Just to be semantic :)
# you do something like
desc "That's my endpoint"
docs "http://docs.example.com/my/endpoint"
# ...and then somewhere...
p my_api.endpoints[:endpoint].describe
# That is my endpoint.
#
# Docs: http://docs.example.com/my/endpoint
# ....
Works for: API, namespace, endpoint
|
# File 'lib/tlaw/dsl.rb', line 54
|
#endpoint(name, path = nil, **opts, &block) ⇒ Object
Defines new endpoint or updates existing one.
Endpoint is the thing doing the real work: providing Ruby API method to really call target API.
NB: If you call endpoint(:something)
and it was already defined,
current definition will be added to existing one (but it can't
change path of existing one, which is reasonable).
Works for: API, namespace
|
# File 'lib/tlaw/dsl.rb', line 238
|
#namespace(name, path = nil, &block) ⇒ Object
Defines new namespace or updates existing one.
Namespace has two roles:
- on Ruby API, defines how you access to the final endpoint,
like
api.namespace1.namespace2(some_param).endpoint(...)
- on calling API, it adds its path to entire URL.
NB: If you call namespace(:something)
and it was already defined,
current definition will be added to existing one (but it can't
change path of existing one, which is reasonable).
Works for: API, namespace
|
# File 'lib/tlaw/dsl.rb', line 168
|
#param(name, type = nil, keyword: true, required: false, **opts) ⇒ Object
Defines parameter for current API (global), namespace or endpoint.
Param defnition defines several things:
- how method definition to call this namespace/endpoint would look like: whether the parameter is keyword or regular argument, whether it is required and what is default value otherwise;
- how parameter is processed: converted and validated from passed value;
- how param is sent to target API: how it will be called in the query string and formatted on call.
Note also those things about params:
- as described in #namespace and #endpoint, setting path template will implicitly set params. You can rewrite this on implicit param call, for ex:
endpoint :foo, '/foo/{bar}'
# call-sequence would be foo(bar = nil)
# But you can make it back keyword:
endpoint :foo, '/foo/{bar}' do
param :bar, keyword: true, default: 'test'
end
# call-sequence now is foo(bar: 'test')
# Or make it strictly required
endpoint :foo, '/foo/{bar}/{baz}' do
param :bar, required: true
param :baz, keyword: true, required: true
end
# call-sequence now is foo(bar, baz:)
- param of outer namespace are passed to API on call from inner namespaces and endpoints, for ex:
namespace :city do
param :city_name
namespace :population do
endpoint :by_year, '/year/{year}'
end
end
# real call:
api.city('London').population.by_year(2015)
# Will get http://api.example.com/city/year/2015?city_name=London
Works for: API, namespace, endpoint
|
# File 'lib/tlaw/dsl.rb', line 76
|
#post_process(&block) ⇒ Object #post_process(key, &block) ⇒ Object
Sets post-processors for response.
There are also #post_process_replace (for replacing entire response with something else) and #post_process_items (for post-processing each item of sub-array).
Notes:
- you can set any number of post-processors of any kind, and they will be applied in exactly the same order they are set;
- you can set post-processors in parent namespace (or for entire API), in this case post-processors of outer namespace are always applied before inner ones. That allow you to define some generic parsing/rewriting on API level, then more specific key postprocessors on endpoints;
- hashes are flattened again after each post-processor, so if
for some
key
you'll return{count: 1, continue: false}
, response hash will immediately have{"key.count" => 1, "key.continue" => false}
.
|
# File 'lib/tlaw/dsl.rb', line 292
|
#post_process_items(key, &block) ⇒ Object
Sets post-processors for each items of array, being at key
(if
the key is present in response, and if its value is array of
hashes).
Inside block
you can use #post_process method as described
above (but all of its actions will be related only to current
item of array).
Example:
Considering API response like:
{
"meta": {"count": 100},
"data": [
{"timestamp": "2016-05-01", "value": "10", "dummy": "foo"},
{"timestamp": "2016-05-02", "value": "13", "dummy": "bar"}
]
}
...you can define postprocessing like this:
post_process_items 'data' do
post_process 'timestamp', &Date.method(:parse)
post_process 'value', &:to_i
post_process('dummy'){nil} # will be removed
end
See also #post_process for some generic explanation of post-processing.
|
# File 'lib/tlaw/dsl.rb', line 343
|
#post_process_replace(&block) ⇒ Object
Just like #post_process for entire response, but replaces it with what block returns.
Real-life usage: WorldBank API typically returns responses this way:
[
{"count": 100, "page": 1},
{"some_data_variable": [{}, {}, {}]}
]
...e.g. metadata and real response as two items in array, not two keys in hash. We can easily fix this:
post_process_replace do |response|
{meta: response.first, data: response.last}
end
See also #post_process for some generic explanation of post-processing.
|
# File 'lib/tlaw/dsl.rb', line 379
|