Class: WSDSL

Inherits:
Object
  • Object
show all
Defined in:
lib/wsdsl.rb,
lib/params.rb,
lib/response.rb,
lib/documentation.rb

Overview

WSDSL offers a web service DSL to define web services, their params, http verbs, formats expected as well as the documentation for all these aspects of a web service.

This DSL is only meant to describe a web service and isn’t meant to cover any type of implementation details. It is meant to be framework/tool agnostic.

However, tools can be built around the Web Service DSL data structure to extract documentation, generate routing information, verify that an incoming request is valid, generate automated tests…

WSDSL
  |
  |__ service options (name, url, SSL, auth required formats, verbs, controller name, action, version, extra)
  |__ defined_params (instance of WSDSL::Params)
  |             |    |  |_ Optional param rules
  |             |    |_ Required param rules
  |             |_ Namespaced params (array containing nested optional and required rules)
  |__ response (instance of WSDSL::Response)
  |      |_ elements (array of elements with each element having a name, type, attributes and vectors
  |      |      |  |_ attributes (array of WSDSL::Response::Attribute, each attribute has a name, a type, a doc and some extra options)
  |      |      |_ vectors (array of WSDSL::Response::Vector), each vector has a name, obj_type, & an array of attributes
  |      |           |_ attributes (array of WSDSL::Response::Attribute, each attribute has a name, a type and a doc)
  |      |_ arrays (like elements but represent an array of objects)
  |
  |__ doc (instance of WSDSL::Documentation)
     |  |  | |_ overal) description
     |  |  |_ examples (array of examples as strings)
     |  |_ params documentation (Hash with the key being the param name and the value being the param documentation)
     |_ response (instance of Documentation.new)
          |_ elements (array of instances of WSDSL::Documentation::ElementDoc, each element has a name and a list of attributes)
                |_ attributes (Hash with the key being the attribute name and the value being the attribute's documentation)

Since:

  • 0.0.3

Defined Under Namespace

Classes: Documentation, Params, Response

Constant Summary collapse

SERVICE_ROOT_REGEXP =

Since:

  • 0.0.3

/(.*?)[\/\(\.]/
SERVICE_ACTION_REGEXP =

Since:

  • 0.0.3

/[\/\(\.]([a-z0-9_]+)[\/\(\.\?]/i
SERVICE_RESTFUL_SHOW_REGEXP =

Since:

  • 0.0.3

/\/:[a-z0-9_]+\.\w{3}$/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url) ⇒ WSDSL

Service constructor which is usually used via Kernel#describe_service

Parameters:

  • url (String)

    Service’s url

See Also:

  • See how this class is usually initialized using `describe_service`

Since:

  • 0.0.3



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/wsdsl.rb', line 123

def initialize(url)
  @url                 = url
  @defined_params      = WSDSL::Params.new
  @doc                 = WSDSL::Documentation.new
  @response            = WSDSL::Response.new
  if WSDSL.use_controller_dispatch
    @name                = extract_service_root_name(url)
    if WSDSL.use_pluralized_controllers
      base_name = ExtlibCopy::Inflection.pluralize(ExtlibCopy::Inflection.singular(name))
      @controller_name     = "#{ExtlibCopy.classify(base_name)}Controller"
    else
      @controller_name     = "#{ExtlibCopy.classify(name)}Controller"
    end
    @action              = extract_service_action(url)
  end
  @verb                = :get
  @formats             = []
  @version             = '0.1'
  @ssl                 = false
  @auth_required       = true
  @extra               = {}
end

Instance Attribute Details

#actionString

Name of the controller action associated with the service

Returns:

  • (String)

Since:

  • 0.0.3



85
86
87
# File 'lib/wsdsl.rb', line 85

def action
  @action
end

#auth_requiredBoolean (readonly)

Is authentication required?

Returns:

  • (Boolean)

Since:

  • 0.0.3



109
110
111
# File 'lib/wsdsl.rb', line 109

def auth_required
  @auth_required
end

#controllerWSController (readonly)

Controller instance associated with the service

Returns:

  • (WSController)

Since:

  • 0.0.3



79
80
81
# File 'lib/wsdsl.rb', line 79

def controller
  @controller
end

#controller_nameString

Name of the controller associated with the service

Returns:

  • (String)

Since:

  • 0.0.3



91
92
93
# File 'lib/wsdsl.rb', line 91

def controller_name
  @controller_name
end

#defined_paramsArray<WSDSL::Params> (readonly)

List of all the service params

Returns:

Since:

  • 0.0.3



55
56
57
# File 'lib/wsdsl.rb', line 55

def defined_params
  @defined_params
end

#docWSDSL::Documentation (readonly)

Documentation instance containing all the service doc

Returns:

Since:

  • 0.0.3



61
62
63
# File 'lib/wsdsl.rb', line 61

def doc
  @doc
end

#extraHash (readonly)

Extra placeholder to store data in based on developer’s discretion.

Returns:

  • (Hash)

    A hash storing extra data based.

Since:

  • 0.1



116
117
118
# File 'lib/wsdsl.rb', line 116

def extra
  @extra
end

#nameString (readonly)

Name of the service

Returns:

  • (String)

Since:

  • 0.0.3



97
98
99
# File 'lib/wsdsl.rb', line 97

def name
  @name
end

#sslBoolean (readonly)

Is SSL required?

Returns:

  • (Boolean)

Since:

  • 0.0.3



103
104
105
# File 'lib/wsdsl.rb', line 103

def ssl
  @ssl
end

#urlString (readonly)

Returns the service url

Returns:

  • (String)

    The service url

Since:

  • 0.0.3



49
50
51
# File 'lib/wsdsl.rb', line 49

def url
  @url
end

#verbSymbol (readonly)

The HTTP verb supported

Returns:

  • (Symbol)

Since:

  • 0.0.3



67
68
69
# File 'lib/wsdsl.rb', line 67

def verb
  @verb
end

#versionString (readonly)

Service’s version

Returns:

  • (String)

Since:

  • 0.0.3



73
74
75
# File 'lib/wsdsl.rb', line 73

def version
  @version
end

Class Method Details

.use_controller_dispatchBoolean

Checks the WSDSL flag to see if controller are used to dispatch requests. This allows apps to use this DSL but route to controller/actions.

Returns:

  • (Boolean)

    The updated value, default to false

Since:

  • 0.3.0



172
173
174
# File 'lib/wsdsl.rb', line 172

def self.use_controller_dispatch
  @controller_dispatch
end

.use_controller_dispatch=(val) ⇒ Boolean

Sets a WSDSL global flag so the controller settings can be generated Setting this flag will automatically set the controller/action names.

Parameters:

  • True (Boolean)

    if the controllers are pluralized, False otherwise.

Returns:

  • (Boolean)

    The updated value

Since:

  • 0.1.1



183
184
185
# File 'lib/wsdsl.rb', line 183

def self.use_controller_dispatch=(val)
  @controller_dispatch = val
end

.use_pluralized_controllersBoolean

Checks the WSDSL flag to see if the controller names are pluralized.

Returns:

  • (Boolean)

    The updated value, default to false

Since:

  • 0.1.1



151
152
153
# File 'lib/wsdsl.rb', line 151

def self.use_pluralized_controllers
  @pluralized_controllers ||= false
end

.use_pluralized_controllers=(val) ⇒ Boolean

Sets a WSDSL global flag so all controller names will be automatically pluralized.

Parameters:

  • True (Boolean)

    if the controllers are pluralized, False otherwise.

Returns:

  • (Boolean)

    The updated value

Since:

  • 0.1.1



162
163
164
# File 'lib/wsdsl.rb', line 162

def self.use_pluralized_controllers=(val)
  @pluralized_controllers = val
end

Instance Method Details

#<=>(other) ⇒ Object

Compare two services using the route loading point

Since:

  • 0.0.3



350
351
352
# File 'lib/wsdsl.rb', line 350

def <=> (other)
  route_loading_point <=> other.route_loading_point
end

#accept_no_params!Nil

Mark the current service as not accepting any params. This is purely for expressing the developer’s objective since by default an error is raise if no params are defined and some params are sent.

Returns:

  • (Nil)

Since:

  • 0.0.3



282
283
284
285
# File 'lib/wsdsl.rb', line 282

def accept_no_params!
  # no op operation since this is the default behavior
  # unless params get defined. Makes sense for documentation tho.
end

#controller_dispatch(app) ⇒ #to_s

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Offers a way to dispatch the service at runtime Basically, it dispatches the request to the defined controller/action The full request cycle looks like that: client -> webserver -> rack -> env -> [service dispatcher] -> controller action -> rack -> webserver -> client

Parameters:

  • app (Object)

    Reference object such as a Sinatra::Application to be passed to the controller.

Returns:

  • (#to_s)

    The response from the controller action

Since:

  • 0.0.3



195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/wsdsl.rb', line 195

def controller_dispatch(app)
  unless @controller
    klass = @controller_name.split("::")
    begin
      @controller = klass.inject(Object) { |const,k| const.const_get(k) }
    rescue NameError => e
      raise "The #{@controller_name} class was not found"
    end
  end
  # We are passing the service object to the controller so the
  # param verification could be done when the controller gets initialized.
  @controller.new(app, self).send(@action)
end

#disable_authBoolean

Mark that the service doesn’t require authentication. Note: Authentication is turned on by default

Returns:

  • (Boolean)

Since:

  • 0.0.3



263
264
265
# File 'lib/wsdsl.rb', line 263

def disable_auth
  @auth_required = false
end

#documentation {|WSDSL::Documentation| ... } ⇒ WSDSL::Documentation

Yields and returns the documentation object

Yields:

Returns:

Since:

  • 0.0.3



328
329
330
# File 'lib/wsdsl.rb', line 328

def documentation
  yield(doc)
end

#enable_sslBoolean

Mark that the service requires a SSL connection

Returns:

  • (Boolean)

Since:

  • 0.0.3



271
272
273
# File 'lib/wsdsl.rb', line 271

def enable_ssl
  @ssl = true
end

#formats(*f_types) ⇒ Array<Symbol>

Sets or returns the supported formats

Parameters:

  • f_types (String, Symbol)

    Format type supported, such as :xml

Returns:

  • (Array<Symbol>)

    List of supported formats

Since:

  • 0.0.3



305
306
307
308
# File 'lib/wsdsl.rb', line 305

def formats(*f_types)
  f_types.each{|f| @formats << f unless @formats.include?(f) }
  @formats
end

#http_verb(s_verb = nil) ⇒ String, Symbol

Sets the accepted HTTP verbs or return it if nothing is passed.

Returns:

  • (String, Symbol)

Since:

  • 0.0.3



314
315
316
317
318
319
320
321
# File 'lib/wsdsl.rb', line 314

def http_verb(s_verb=nil)
  return @verb if s_verb.nil?
  @verb = s_verb.to_sym
  # Depending on the service settings and url, the service action might need to be updated.
  # This is how we can support restful routes where a PUT request automatically uses the update method.
  update_restful_action(@verb)
  @verb
end

#nested_paramsArray<WSDSL::Params>

Returns an array of namespaced params

Returns:

See Also:

Since:

  • 0.0.3



254
255
256
# File 'lib/wsdsl.rb', line 254

def nested_params
  @defined_params.namespaced_params
end

#optional_rulesArray<WSDSL::Params::Rule>

Returns an array of optional param rules

Returns:

Since:

  • 0.0.3



245
246
247
# File 'lib/wsdsl.rb', line 245

def optional_rules
  @defined_params.list_optional
end

#paramsWSDSL::Params Also known as: param

Returns the defined params for DSL use only! To keep the distinction between the request params and the service params using the defined_params accessor is recommended.

Returns:

See Also:

Since:

  • 0.0.3



217
218
219
220
221
222
223
# File 'lib/wsdsl.rb', line 217

def params
  if block_given?
    yield(@defined_params)
  else
    @defined_params
  end
end

#params?Boolean

Returns true if the DSL defined any params

Returns:

  • (Boolean)

Since:

  • 0.0.3



229
230
231
# File 'lib/wsdsl.rb', line 229

def params?
  !(required_rules.empty? && optional_rules.empty? && nested_params.empty?)
end

#required_rulesArray<WSDSL::Params::Rule>

Returns an array of required param rules

Returns:

Since:

  • 0.0.3



237
238
239
# File 'lib/wsdsl.rb', line 237

def required_rules
  @defined_params.list_required
end

#response { ... } ⇒ WSDSL::Response

Returns the service response

Yields:

  • The service response object

Returns:

Since:

  • 0.0.3



292
293
294
295
296
297
298
# File 'lib/wsdsl.rb', line 292

def response
  if block_given?
    yield(@response)
  else
    @response
  end
end

#route_loading_pointInteger

Assign a route loading point to compare two routes. Using this point value, one can load routes with the more globbing routes later than short routes.

Returns:

  • (Integer)

    point value

Since:

  • 0.0.3



337
338
339
340
341
342
343
344
345
346
347
# File 'lib/wsdsl.rb', line 337

def route_loading_point
  url =~ /(.*?):(.*?)[\/\.](.*)/
  return url.size if $1.nil?
  # The shortest the prepend, the further the service should be loaded
  prepend = $1.size
  # The shortest the placeholder, the further it should be in the queue
  place_holder = $2.size
   # The shortest the trail, the further it should be in the queue
  trail = $3.size
  prepend + place_holder + trail
end