Skip to content

Instantly share code, notes, and snippets.

@adammck
Last active December 17, 2015 16:30
Show Gist options
  • Save adammck/5639645 to your computer and use it in GitHub Desktop.
Save adammck/5639645 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
require "uri"
require "net/http"
require "json"
module API
def self.start(url)
parse(get(url))
end
def self.get(url)
#$stderr.puts "GET: #{url}"
Net::HTTP.get(URI(url))
end
def self.parse(json)
JSON.parse(json, options)
end
def self.options
{
symbolize_names: true,
object_class: Object,
array_class: Array
}
end
class Object < ::Hash
def method_missing(key, *args)
u = "#{key}_url".to_sym
if include?(u)
API.start(self[u])
elsif include?(key)
self[key]
else
super
end
end
end
class Array < ::Array
end
end
#!/usr/bin/ruby
require "./client"
api = API.start("http://localhost:4567")
puts api.blogs.first.name
# => My Favorite Photos of Cats
puts api.blogs.first.posts.last.title
# => Look at this hilarious cat
puts api.blogs.first.posts.last.author.username
# => adammck
puts api.blogs.first.posts.last.full.body
# => ...
puts api.blogs.first.posts.last.author.posts.first.title
# => Welcome to my cat blog
source "https://rubygems.org"
gem "sinatra"
gem "sinatra-contrib"
gem "sequel"
gem "sqlite3"
gem "multi_json"
group :development do
gem "shotgun"
gem "thin"
end
#!/usr/bin/ruby
require "sequel"
require "sinatra"
require "multi_json"
require "sinatra/json"
DB = Sequel.sqlite
# ------------------------------------------------------------------------------
DB.create_table :users do
primary_key :id
String :username
String :email
String :real_name
end
DB.create_table :blogs do
primary_key :id
String :name
end
DB.create_table :posts do
primary_key :id
foreign_key :blog_id, :blogs
foreign_key :author_id, :users
String :title
String :body
end
# ------------------------------------------------------------------------------
DB[:users].tap do |t|
t.insert id: 1, username: "adammck", email: "[email protected]", real_name: "Adam Mckaig"
end
DB[:blogs].tap do |t|
t.insert id: 1, name: "My Favorite Photos of Cats"
t.insert id: 2, name: "My Serious Work Blog"
end
DB[:posts].tap do |t|
t.insert id: 1, blog_id: 1, author_id: 1, title: "Welcome to my cat blog", body: "..."
t.insert id: 2, blog_id: 1, author_id: 1, title: "OMG this cat is so funny", body: "..."
t.insert id: 3, blog_id: 1, author_id: 1, title: "Look at this hilarious cat", body: "..."
end
# ------------------------------------------------------------------------------
def user_as_json(user)
{
username: user[:username],
email: user[:email],
real_name: user[:real_name],
self_url: url("/users/#{user[:id]}"),
posts_url: url("/users/#{user[:id]}/posts"),
blogs_url: url("/users/#{user[:id]}/blogs")
}
end
def blog_as_json(blog)
{
name: blog[:name],
self_url: url("/blogs/#{blog[:id]}"),
posts_url: url("/blogs/#{blog[:id]}/posts"),
}
end
def short_post_as_json(post)
{
title: post[:title],
full_url: url("/posts/#{post[:id]}"),
author_url: url("/users/#{post[:author_id]}")
}
end
def full_post_as_json(post)
{
title: post[:title],
body: post[:body],
self_url: url("/posts/#{post[:id]}"),
author_url: url("/users/#{post[:author_id]}")
}
end
# ------------------------------------------------------------------------------
get "/" do
json({
users_url: url("/users"),
blogs_url: url("/blogs")
})
end
get "/users" do
json(DB[:users].map do |user|
user_as_json(user)
end)
end
get "/users/:id" do
json(user_as_json(DB[:users][id: params[:id]]))
end
get "/users/:id/posts" do
json(DB[:posts].where(author_id: params[:id]).map do |post|
short_post_as_json(post)
end)
end
get "/blogs" do
json(DB[:blogs].map do |blog|
blog_as_json(blog)
end)
end
get "/blogs/:id" do
json(blog_as_json(DB[:blogs][id: params[:id]]))
end
get "/blogs/:id/posts" do
json(DB[:posts].where(blog_id: params[:id]).map do |post|
short_post_as_json(post)
end)
end
get "/posts" do
json(DB[:posts].map do |post|
short_post_as_json(post)
end)
end
get "/posts/:id" do
json(full_post_as_json(DB[:posts][id: params[:id]]))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment