tastypie v6.0.0
node-tastypie
A re-realization of the popular Django REST framework - Tasypie for Node.js
- Project is very
Alpha
and missing a lot of features and functionality. Do not use for any production apps currently
Create a simple Api
var tastypie = require('tastypie')
var Api = tastypie.Api
var Resource = tastypie.Resource
var app = require('express')();
var v1 = new Api('api/v1', app)
v1.register('test', new Resource() );
app.listen( 3000 );
This allows for full HTTP support and basic CRUD operations on a single enpoint - api/v1/test
curl -XPOST -H "Content-Type: applciation/json" -d '{"test":"fake"}' http://localhost:3000/api/v1/test
curl -XPUT -H "Content-Type: applciation/json" -d '{"test":"real"}' http://localhost:3000/api/v1/test
curl -XDELETE http://localhost:3000/api/v1/test/fake
Serialization
The base serializer can deal with xml
, json
and jsonp
out of the box. Serialization method is determined by the Accept
header or a format
query string param
curl -H "Accept: application/xml" http://localhost:3000/api/v1/test
curl http://localhost:3000/api/v1/test?format=xml
FIXMEs
- currently implemented ontop of express. Would like to move to Hapi.js - The hapi request interface is mostly the same, and the parts - Paginator, Serializer, Cache can be used just find with hapi out side of the Resource Class in Hapi plugins and route handlers just fine
What is Broke ?
- Request flow for all HTTP Methods is yet to be fleshed out. Mostly data hydration
- All APIFields are yet to be fleshed out
- Schema endpoints
- Notion of streaming responses...
What Works ?
- Serialization / Desrialization in xml, json, and serialization in JSONP
- Paginators.
- Caching
- GET, POST & PUT
- Resources do not assume any ORM or backend, so the default resource does nothing. You will have to subclass and define all internal methods. Get is mostly done for you.
- Per Field dyhdration.
- APIField inheritance
Example FS resourse
Here is a resource that will asyncronously read a JSON file from disk are respond to GET requests. Supports XML, JSON, paging and dummy cache out of the box.
var Resource = require('./lib/resource')
var Api = require('./lib/api')
var app = require('express')();
var fields = require("./lib/fields")
var Class = require('./lib/class')
var fs = require('fs')
var path = require('path')
var debug = require('debug')('tastypie:simple')
var R = new Class({
inherits: Resource
,resourceName:'lookup'
,methodsAllowed:{
get:true
}
,fields:{
test:{
attribute:'id'
,type:'ApiField'
}
}
// Called by get_list to get the data, does caching
,_get_list: function( bundle, callback ){
var key = this.cacheKey(
"list"
,bundle.req.api_name
,bundle.req.uri
,bundle.req.method
,this.meta.name
,bundle.req.query
,bundle.req.params
)
var that = this;
this.meta.cache.get(key, function( err, data ){
debug('cache return')
if( data ){
debug("cached")
return callback( null, data )
}
// Reads a file name data.json from disk
fs.readFile(path.resolve("./data.json"), 'utf8', function(err, contents){
debug("file return")
that.meta.cache.set( key, contents)
callback( null, contents )
})
})
}
// handles a put request to an specific instance
,put_detail: function( bundle ){
var format = this.format(bundle, this.meta.serializer.types )
this.deserialize( bundle.req.body, format, function(err, data ){
console.log( data );
bundle = this.update_object( bundle )
bundle.data = this.full_dehydrate( bundle.data )
return this.respond(bundle)
}.bind( this ) )
}
// per field dehydration method - maps the test field value to id
,dehydrate_test: function( obj ){
return obj.id
}
,update_object: function(bundle){
return bundle
}
// method that retreives an individual object by id.
// becuase it's in a flat file, read it, filter and return first object
,get_object: function(bundle, callback){
this._get_list(bundle,function(e, objects){
var obj = JSON.parse( objects ).filter(function( obj ){
return obj.id = bundle.req.params.id
})[0]
callback( null, obj )
})
}
});
var counter = 0;
var api = new Api('api/v1', app,{
middleware:[
function(req, res, next){
console.log("request %d", ++counter)
next()
}
]
});
api.register('test', new R );
app.listen(process.env.PORT || 2000);
Now you can read data from a file with your rest API
curl http://localhost:2000/api/v1/test
curl http://localhost:2000/api/v1/test?format=xml
curl http://localhost:2000/api/v1/test/1
curl http://localhost:2000/api/v1/test/2
curl http://localhost:2000/api/v1/test/2?format=xml
Contributing
Contributions & patches welcome. If you have experience working with the original python / django-tastypie, input would be greatly appreciated. Anything from docs, test and feature code is fair game.
- Fork
- Write Code
- Write tests
- Document your code
- Push
- Open Pull Request
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago