• Stars
    star
    519
  • Rank 85,279 (Top 2 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 12 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Parameter Validation & Type Coercion for Sinatra

sinatra-param

Parameter Validation & Type Coercion for Sinatra

REST conventions take the guesswork out of designing and consuming web APIs. Simply GET, POST, PATCH, or DELETE resource endpoints, and you get what you'd expect.

However, when it comes to figuring out what parameters are expected... well, all bets are off.

This Sinatra extension takes a first step to solving this problem on the developer side

sinatra-param allows you to declare, validate, and transform endpoint parameters as you would in frameworks like ActiveModel or DataMapper.

Use sinatra-param in combination with Rack::PostBodyContentTypeParser and Rack::NestedParams to automatically parameterize JSON POST bodies and nested parameters.

Install

You can install sinatra-param from the command line with the following:

$ gem install sinatra-param

Alternatively, you can specify sinatra-param as a dependency in your Gemfile and run $ bundle install:

gem "sinatra-param", require: "sinatra/param"

Example

require 'sinatra/base'
require 'sinatra/param'
require 'json'

class App < Sinatra::Base
  helpers Sinatra::Param

  before do
    content_type :json
  end

  # GET /search?q=example
  # GET /search?q=example&categories=news
  # GET /search?q=example&sort=created_at&order=ASC
  get '/search' do
    param :q,           String, required: true
    param :categories,  Array
    param :sort,        String, default: "title"
    param :order,       String, in: ["ASC", "DESC"], transform: :upcase, default: "ASC"
    param :price,       String, format: /[<\=>]\s*\$\d+/

    one_of :q, :categories

    {...}.to_json
  end
end

Parameter Types

By declaring parameter types, incoming parameters will automatically be transformed into an object of that type. For instance, if a param is Boolean, values of '1', 'true', 't', 'yes', and 'y' will be automatically transformed into true.

  • String
  • Integer
  • Float
  • Boolean ("1/0", "true/false", "t/f", "yes/no", "y/n")
  • Array ("1,2,3,4,5")
  • Hash (key1:value1,key2:value2)
  • Date, Time, & DateTime

Validations

Encapsulate business logic in a consistent way with validations. If a parameter does not satisfy a particular condition, a 400 error is returned with a message explaining the failure.

  • required
  • blank
  • is
  • in, within, range
  • min / max
  • min_length / max_length
  • format

Custom Error Messages

Passing a message option allows you to customize the message for any validation error that occurs.

param :spelling,
      format: /\b(?![a-z]*cie)[a-z]*(?:cei|ie)[a-z]*/i,
      message: "'i' before 'e', except after 'c'"

Defaults and Transformations

Passing a default option will provide a default value for a parameter if none is passed. A default can defined as either a default or as a Proc:

param :attribution, String, default: "Β©"
param :year, Integer, default: lambda { Time.now.year }

Use the transform option to take even more of the business logic of parameter I/O out of your code. Anything that responds to to_proc (including Proc and symbols) will do.

param :order, String, in: ["ASC", "DESC"], transform: :upcase, default: "ASC"
param :offset, Integer, min: 0, transform: lambda {|n| n - (n % 10)}

One Of

Using one_of, routes can specify two or more parameters to be mutually exclusive, and fail if more than one of those parameters is provided:

param :a, String
param :b, String
param :c, String

one_of :a, :b, :c

Any Of

Using any_of, a route can specify that at least one of two or more parameters are required, and fail if none of them are provided:

param :x, String
param :y, String

any_of :x, :y

All Or None Of

Using all_or_none_of, a router can specify that all or none of a set of parameters are required, and fail if some are provided:

param :x, String
param :y, String

all_or_none_of :x,:y

Exceptions

By default, when a parameter precondition fails, Sinatra::Param will halt 400 with an error message:

{
  "message": "Parameter must be within [\"ASC\", \"DESC\"]",
  "errors": {
    "order": "Parameter must be within [\"ASC\", \"DESC\"]"
  }
}

To change this, you can set :raise_sinatra_param_exceptions to true, and intercept Sinatra::Param::InvalidParameterError with a Sinatra error do...end block. (To make this work in development, set :show_exceptions to false and :raise_errors to true):

set :raise_sinatra_param_exceptions, true

error Sinatra::Param::InvalidParameterError do
    { error: "#{env['sinatra.error'].param} is invalid" }.to_json
end

Custom exception handling can also be enabled on an individual parameter basis, by passing the raise option:

param :order, String, in: ["ASC", "DESC"], raise: true

one_of :q, :categories, raise: true

Contact

Mattt (@mattt)

License

sinatra-param is released under an MIT license. See LICENSE for more information.

More Repositories

1

Ono

A sensible way to deal with XML & HTML for iOS & macOS
Objective-C
2,603
star
2

GroundControl

Remote configuration for iOS
Objective-C
1,946
star
3

CargoBay

The Essential StoreKit Companion
Objective-C
1,770
star
4

Euler

Swift Custom Operators for Mathematical Notation
Swift
1,156
star
5

AnimatedGIFImageSerialization

Complete Animated GIF Support for iOS, with Functions, NSJSONSerialization-style Class, and (Optional) UIImage Swizzling
Objective-C
1,087
star
6

TransformerKit

A block-based API for NSValueTransformer, with a growing collection of useful examples.
Objective-C
848
star
7

Navajo

Password Validator & Strength Evaluator
Objective-C
836
star
8

SkyLab

Multivariate & A/B Testing for iOS and Mac
Objective-C
790
star
9

Orbiter

Push Notification Registration for iOS
Objective-C
673
star
10

NSEtcHosts

/etc/hosts with NSURLProtocol
Objective-C
666
star
11

Chroma-Hash

A colorful visualization of password field input
JavaScript
624
star
12

rack-scaffold

Automatically generate REST APIs from Core Data models
Ruby
528
star
13

InflectorKit

Efficiently Singularize and Pluralize Strings
Objective-C
476
star
14

NSSortDescriptor-WilsonRank

The Correct Way To Rank Up/Down Voted Items
Objective-C
433
star
15

Antenna

Extensible Remote Logging for iOS
Objective-C
424
star
16

Godzippa

Godzippa! - GZip Compression / Decompression Category for NSData
Objective-C
424
star
17

CommonMarkAttributedString

Create NSAttributedStrings from Markdown Text
Swift
421
star
18

rack-push-notification

A Rack-mountable webservice for managing push notifications
Ruby
378
star
19

TTTLocalizedPluralString

NSLocalizedString with a Count Argument
Objective-C
378
star
20

CupertinoYankee

An NSDate Category With Locale-Aware Calculations for Beginning & End of Day, Week, Month, and Year
Objective-C
305
star
21

WebPImageSerialization

Complete WebP Support for iOS, with Functions, NSJSONSerialization-style Class, and (Optional) UIImage Swizzling
C
282
star
22

CHChromaHashView

A classic password visualization concept, ported to iOS
Objective-C
273
star
23

Xcode-Licensed-Templates

Minimal Xcode Templates for Open Source Developers
255
star
24

GeoJSONSerialization

Encode & Decode Between GeoJSON & MapKit Shapes
Objective-C
231
star
25

terminal-share

Command Line & Ruby Interface to Mac OS X Sharing Services
Objective-C
228
star
26

TTTRandomizedEnumerator

Mix things up with your collection classes with style and class (well, a category, but you get the idea).
Objective-C
223
star
27

BritishInvasion

Localise Your .m Files, For Queen And Country πŸ‡¬πŸ‡§
Objective-C
212
star
28

OpenAI

A Swift client for the OpenAI API.
Swift
181
star
29

AnyJSON

Encode / Decode JSON By Any Means Possibleβ„’
Objective-C
119
star
30

MsgPackSerialization

MsgPack Serialization for Objective-C
C
96
star
31

Morse.js

A jQuery Plugin to annotate text with Morse Code
JavaScript
95
star
32

rack-smart-app-banner

Rack middleware to automatically include code for Smart App Banners on iOS
Ruby
85
star
33

vCardSerialization

Encodes and decodes between vCard files and AddressBook records.
Objective-C
69
star
34

UIFontSerialization

Encode and decode between UIFont and Postscript font data
Objective-C
64
star
35

rack-http-logger

Log metrics from HTTP request parameters according to l2met conventions
Ruby
57
star
36

rack-passbook

Rack middleware that provides Passbook web service endpoints.
Ruby
52
star
37

rack-in-app-purchase

Rack middleware that manages products for in-app-purchases and verifies receipts.
Ruby
51
star
38

swift-package-registry-oas

OpenAPI Specification for proposed Swift Package Registry web service
Swift
41
star
39

core_data

Parse Core Data Model (.xcdatamodel) Files
Ruby
39
star
40

swift-registry

A reference implementation of the Swift Package Registry, written in Swift and using Git as a database / transparent log.
Swift
37
star
41

rack-subdomain

Rack middleware to transparently route requests with a subdomain to a specified path with substitutions
Ruby
37
star
42

rack-newsstand

Automatically generate webservice endpoints for Newsstand
Ruby
33
star
43

rack-remote-configuration

Serve property list or JSON configuration files
Ruby
24
star
44

commoditize

A command-line utility for macOS that mounts a Docker container image as an external disk image.
Shell
20
star
45

swift-package-sbom

A software bill of materials (SBoM) generator for Swift packages
Swift
17
star
46

vscode-unicorn

πŸ¦„πŸ’¬ A Visual Studio Code extension that adds a status bar entry showing Unicode data for the currently selected character.
TypeScript
15
star
47

hype

Write Python functions. Call them from language models.
Python
15
star
48

Sonic-Hash

A melodic Sonification of password field input
JavaScript
14
star
49

NFPA704View

UIView Subclass for NFPA 704 "Fire Diamonds"
Objective-C
13
star
50

swift-package-registry-codeartifact

A basic implementation of the Swift package registry interface that uses AWS CodeArtifact as a backend for package releases and assets.
TypeScript
10
star
51

rack-heroku-no-such-app

Rack middleware to prevent loading from `*.heroku.com` / `*.herokuapp.com` addresses
Ruby
9
star
52

glitz

Glitz adds ANSI-colorized glamour to your terminal output
Ruby
9
star
53

replicate-swift

Unofficial Swift client for the Replicate API
Swift
8
star
54

swift-package-serialization-lambda

Swift
7
star
55

cog-replicate-logo-generator

Python
5
star
56

rack-typekit

Rack middleware to automatically inject Typekit into webpages
Ruby
4
star
57

CycloneDX

Swift
4
star
58

swift-registry-benchmark-harness

A harness for benchmarking the performance of building a project with Swift Package Manager using the new package registry interface.
Ruby
4
star
59

documentation-block

[WIP] View symbol documentation for a file
TypeScript
3
star
60

swift-evolution

This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Markdown
1
star