Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

contrackt

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

contrackt

  • 0.0.0
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

Contrackt is a tool to make handling request and response objects more object-oriented.

In general, Ruby handles these request and response objects mostly using hashes. One would expect to see something along the lines of

{
	body: {
    "foo" => {
      "bar" => "baz"
    }
  }
}

So your code might involve accessing variables like response[:body]['foo']['bar'] (always keeping track of which key is a string and which is a symbol) instead of the more object-oriented response.body.foo.bar. Contracts are an attempt to represent these JSON hashes more clearly based on the objects they represent.

Contrackt allows the user to define self-documenting "contracts" that they expect to receive or send based on whatever API tool (raml, swagger, blueprint) they use to specify an API. An example usage is

class MyContract < Contrackt::Base
  required 'foo' => Foo
end

class Foo < Contrackt::Base
  required 'bar'
end

You can then use those classes to work with the resulting JSON, e.g.

# json_response = { body: { "foo" => { "bar" => "baz" } } }
contract = MyContract.new(json_response[:body])
contract.foo.bar #=> 'baz'
contract.to_hash #=> { "foo" => { "bar" => "baz" } }

You can also specify arrays of type:

# json = { albums: [{ name: "21", artist: "Adele" }, { name: "IV", artist: "Led Zeppelin" }] }

class Album < Contrackt::Base
  required :name
  required :artist
end

class AlbumPayload < Contrackt::Base
  required albums: Album[]
end

The RAML spec provides for the concept of a "discriminator," i.e. a field that indicates the object's type. You can specify a discriminator as follows:

# json = { pets:
#   [
#      { type: "Cat", name: "Garfield", owner: "Jon", color: "striped" },
#      { type: "Dog", name: "Marmaduke", owner: "Phil", breed: "great dane" },
#      ...
#   ]
# }

class Pet < Contrackt::Base
  discriminator :type
  required      :name
  required      :owner
end

class PetsPayload < Contrackt::Base
  required pets: Pet[]
end

class Cat < Pet
  required :color
end

class Dog < Pet
  required :breed
end

You can also use discriminator along with a map if the discriminator doesn't provide the class name:

# json = { pets:
#   [
#      { type: "cat", name: "Garfield", owner: "Jon", color: "striped" },
#      { type: "dog", name: "Marmaduke", owner: "Phil", breed: "great dane" },
#      ...
#   ]
# }

class Pet < Contrackt::Base
  discriminator :type, 'cat' => Cat, 'dog' => Dog
  required      :name
  required      :owner
end

class PetsPayload < Contrackt::Base
  required pets: Pet[]
end

class Cat < Pet
  required :color
end

class Dog < Pet
  required :breed
end

If you have complicated code, you can write a custom parser, e.g.

# json = { foo: 'bar' }

class Thing < Contrackt::Base
  required(:foo).with_custom_parser { |json| "#{json} (came from key foo)" }
end

Thing.new(json).foo #=> "bar (came from key foo)"

FAQs

Package last updated on 28 Feb 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc