auto-api-middleware

0.5.5 • Public • Published

Auto API Middleware

Do you want all / a subset of the methods on your backend classes/objects/models/some {} to be fetch-able or $.ajax-able on the front without having to write explicit express routes?

Then add them to your router like so:

.all("/json(/:model)?(/:verb)?", require("auto-api-middleware")({source:Model}) )

Example

Say a Model was passed in that looked like this:

var Model={
	book:{
		getPage(num){}
		,getWordsByFrequency(isbn){}
		,fetchCover(isbn){}
	}
	,scheduler:{
		setAppointment(){}
		,getEventsInRange(start,end){}
	}
	,user:{
		get(key){}
		,update(key,changes){}
		,columns:{name:'',created:'',password:'',email:''}
	}
}

That would create these JSON routes:

/json/book/getPage
/json/book/getWordsByFrequency
/json/book/fetchCover
/json/scheduler/setAppointment
/json/scheduler/getEventsInRange
/json/user/get
/json/user/update
/json/user/columns

All routes for functions with named inputs would require them as URL query parameters like so:

$.ajax({url:"/json/scheduler/getEventsInRange",data:{start:"Tuesday",end:"Friday"}})
//or
fetch("/json/scheduler/getEventsInRange?start=Tuesday&end=Friday")

These flow types are understood for functions:

  • (async) If a function signature has an input that is named in callbackNames (see options below), it will use that
  • (promise) If a function returns a promise, it will send the resolution
  • (sync) If a function returns anything else, that value is sent

Now, maybe you:

  • don't want user.update to be available
  • or want to restrict it to only be in the scope of the session's user
  • or want to only take methods containing certain words

The options below allow that.

Options

//note the path is left to you to define, but :model and :verb are required somehow.
//this path allows both to be optional, which makes it easier to beHelpful
.all("/json(/:model)?(/:verb)?", require("auto-api-middleware")({
	//opt:default value if you don't provide one
	source:{} //should be shaped like {model1:{verbs},model2:{verbs},...}; compose as you'd like. Only take things at M.json.*?
	,beHelpful:false // suggest models, verbs, and inputs necessary for incomplete requests. Keep off in production.
	,filter(key,val){ //restrict which model properties to make available. Return truthy here to keep.
		//key=verb, val=source[model][verb] in these cases
		return !(key[0]=='_' || val.priv || val.private) //recall properties can be assigned to functions, if you want
	}
	,methodMap(key,value){  // which HTTP method to use for which methods.
		return _.castArray(
			(key.match(/^(get|gather|find|fetch)/gi) || !_.isFunction(value) ? "GET"
			: key.match(/POST|GET|PUT|PATCH|DELETE/i)
			) || "POST"
		).first()
	}
	,before(req,res){} // sync run before verb. Say, force anything called user_id to be the session's user_id...
	,after(req,res,returned){} //sync run after verb to allow transforms of returned value before responding
	,callbackNames:["done","next","then","cb","callback"] //place the res.send callback in the first input named one of these
										  // (otherwise assume promise or sync result)
}) )

Package Sidebar

Install

npm i auto-api-middleware

Weekly Downloads

1

Version

0.5.5

License

MIT

Last publish

Collaborators

  • jnvm