Skip to content

Instantly share code, notes, and snippets.

@AlexeyMK
Created February 14, 2012 05:35
Show Gist options
  • Save AlexeyMK/1823921 to your computer and use it in GitHub Desktop.
Save AlexeyMK/1823921 to your computer and use it in GitHub Desktop.
JSON API Design Prototype
# Just a prototype of a JSON API framework that I thought up because it'd be nice to have
# for API work I've done before - feedback very much welcome.
#
# all models have a 'short' and a full version
@canonical_url('/users/:id')
class User(Model): # this model is both an ORM-style model and a REST resource.
id = ModelField.Integer(unique=True)
name = ModelField.String(length=25)
email = ModelField.String(length=55, in_short=None)
listing = ModelField.Reference('Listing', in_short=None, in_full="link") # other options: [None, Link, Short, Full]
password = ModelField.HashedString(length=255, hide_from_api=True)
# the 'user' method isn't strictly necessary (it would have been auto-generated
# via smart defaults from @canonical_url class decorator)
@expose(path="/users/:id", format="full")
def user(self, id):
return cls.objects.get(id=id)
"""{"id"=1,
"name"="Bob Graham",
"url"="http://website.com/user/1",
"email"="bob@graham.net",
"listing"="http://website.com/listing/1"
}"""
@expose(path="/users", format="short")
def users(self):
return cls.objects.all() #automatically as JSON
"""
[{"id"=1,
"name"="Bob Graham",
"url"="http://website.com/user/1"},
{"id"=2,
"name"="Sally Fields",
"url"="http://website.com/user/2"}
]
"""
@expose(path="/listings/:listing_id/owner", format="full")
def owner_of_listing(self, listing_id):
return Listing.objects.get(id=listing_id).owner
"""{"id"=1,
"name"="Bob Graham",
"url"="http://website.com/user/1",
"email"="bob@graham.net",
"listing"="http://website.com/listing/1"
}"""
# ideas for a more advanced version:
#
# class User(Model):
# ...
# listing = ModelField.Reference('listing', in_short=None, in_full="link", follow_on="listing")
# ...
#
# and then, whenever the dispatcher has brought us to a User at some arbitrary path "/a/b/c",
# we can do "/a/b/c/listing" to get that user's listing (and, if you wanted to be silly
# and set it up in both directions, "/a/b/c/listing/user/listing/user/...")
#
# Not yet addressed:
# - attributes which can be GET/PUT/POST/DELETEd based on user's permission level
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment