jap
v1.2.1
Published
JSON Action Protocol
Downloads
23
Readme
JSON Action Protocol
An idea
You may use it on server and browser side or native apps, anywhere.
This is just an idea how we can run actions of other apps from our.
J.A.P. provides you running of all actions you need in one request via json.
####Request example
{
"user": {
"icon": "small",
"balance": "all",
"properties": ["name", "age"],
"test": false
},
"payment": {
"methods": [0, 2]
},
"cart": {
"count": null,
"items": 4
}
}
Response for the example
{
"user": {
"icon": {
"success": true,
"data": "/img/...jpg"
},
"balance": {
"success": true,
"data": {
"cash": 420,
"points": 13
}
},
"properties": {
"success": true,
"data": {
"name": "Mike",
"age": 42
}
},
"test": {
"error": "Undeclared handler",
"data": false
}
},
"payment": {
"methods": {
"success": true,
"data": [
{"id": 7, "type": "html"},
{"id": 12, "type": "iframe"}
]
}
},
"cart": {
"count": {
"success": true,
"data": 4
},
"items": {
"error": "The item is not found",
"data": 4
}
}
}
About jap
function
The function helps you handle any J.A.P. request.jap (
- [ primitiveHandler: json primitive | handler: function | handlerCollection: array | handlerList: object ]: parsed JSON with functions
- [, request: json primitive | requestCollection: array | requestList: object ]: parsed JSON
- [, resolve: function ]
- [, reject: function ]
- [, promises: array ]
- [, context: any ]
)
Resolve
If all rules are followed and handler is finished without errors then the result will go through resolve callback function. You will see all rules in this section.
jap(primitiveHandler
)
primitiveHandler
is any primitive value of json null
, boolean
, number
or string
.jap
with primitiveHandler
always returns the handler.
jap(null) // returns {success: true, data: null}
jap(false) // returns {success: true, data: false}
jap(1) // returns {success: true, data: 1}
jap(1.1) // returns {success: true, data: 1.1}
jap('string') // returns {success: true, data: 'string'}
jap(handler
)
handler
is a function.jap
with handler
always returns result of handler
's call.
jap(() => 1) // returns {success: true, data: 1}
jap(() => {}) // returns {success: true, data: null}
jap(handler, request
)
request
is a parsed json from another app.
You may handle request
by handler
.handler
gets request
as the first argument.
jap(x => x + x, 1) // returns {success: true, data: 2}
jap(x => !x, true) // returns {success: true, data: false}
jap(x => x.test, {test: 1}) // returns {success: true, data: 1}
jap(handler, requestCollection
)
You may provide any count of arguments to handler
by requestCollection
.requestCollection
just is an array of arguments.
const sum = (x, y) => x + y
jap(sum, [1, 2]) // returns {success: true, data: 3}
jap(sum, [3, 5]) // returns {success: true, data: 8}
jap(handler, request, resolve
)
Default resolve
is data => ({success: true, data})
.
But you can change it as you wish
const sum = (x, y) => x + y
jap(sum, [1, 2], data => data) // returns 3
You may use true
if you want to set default resolve
function and false
if you want to return only request data
const sum = (x, y) => x + y
jap(sum, [1, 2], true) // returns {success: true, data: 3}
jap(sum, [1, 2], false) // returns 3
jap(handlerCollection
, request, resolve)
You may use an array of any handlers type as handlerCollection
.
Each next handler gets result of handle before.
const sum = (x, y) => x + y
const square = x => x * x
jap([sum, square], [1, 2]) // returns {success: true, data: 9}
jap(handlerList
, requestList
)
handlerList
works only with requestList
. They booth are objects.
You may see whats happen if handlerList
runs without requestList
here
Fields of handlerList
are any handler type and fields of requestList
are any request type.
const sum = (x, y) => x + y
const square = x => x * x
const math = {sum, square}
jap(math, {square: 4}, false) // returns {square: 16}
jap(math, {square: 3, sum: [3, 4]}, false) // returns {square: 9, sum: 7}
const core = {math, version: '1.0.0'}
jap(core, {math: {square: 5}}, false) // returns {math: {square: 25}}
jap(core, {math: {sum: [5, 7]}, version: null}, false) // returns {math: {sum: 12}, version: '1.0.0'}
resolve is using only for primitiveHandler
or handler
const response = JSON.stringify(jap(core, {math: {sum: [5, 7]}, version: null}))
returns
{
"math": {
"sum": {
"success": true,
"data": 12
}
},
"version": {
"success": true,
"data": "1.0.0"
}
}
You may pass it to response and handle the response on client by jap
jap({
math: {
sum ({success, data}) {
if (success) {
console.log('set sum and update this information on the page', data)
}
}
},
version ({success, data}) {
if (success) {
console.log('update version and run all actions you need', data)
}
}
}, JSON.parse(response))
jap
does not create new object, it changesrequestList
all keys starts from
_
or$
are private and unavailable outside
Reject
If any rules are failed or handler is finished with an error then the result will go
through reject callback function.
You will see all rules for that in this section.
Default reject callback function is (data, error, handler) => ({error: error.message, data})
.data
is data from requesterror
is an instance of Error
handler
is a handler which threw the error
Wrong handler
If your handler is not matched with primitiveHandler, handler, handlerCollection or handlerList
Then jap
returns reject
(null
is default request)
And you get an error with message Undeclared handler
jap() // returns {error: 'Undeclared handler', data: null}
jap(undefined) // returns {error: 'Undeclared handler', data: null}
jap(Symbol()) // returns {error: 'Undeclared handler', data: null}
jap(NaN, 'test') // returns {error: 'Undeclared handler', data: 'test'}
Wrong request
If your handler
is handlerList
and request
is not requestList
then you get an error with message Undeclared request
jap({}) // returns {error: 'Undeclared request', data: null}
Wrong handlerCollection
If handlerCollection contains wrong handler then jap
stops handling on wrong element and returns request or the last result of success handlerCollection's element as request
jap([1, undefined], 2, true, (data, error, handler) => ({data, error, handler}))
// returns {data: 1, error: Error('Undeclared handler'), handler: undefined}
empty
handlerCollection
is legal handler which goes through resolve
Promises
You may use async handlers, all promises returned the handlers will be added to the promises
argument of jap
const handler = {
test1: async e => {
await new Promise(resolve => setTimeout(resolve, 10))
return e
},
test2: async () => {
throw Error('test')
}
}
const promises = []
const result = jap(handler, {test1: 1, test2: 2}, true, true, promises)
// promises.length equals 2
// result.test1 is promise
// result.test1 === promises[0]
Promise.all(promises).then(() => {
// result.test1 is {success: true, data: 1}
// result.test2 is {error: 'test', data: 2}
})
TODO example
You may look at real example with:
git clone https://github.com/d8corp/jap.git
cd jap
npm i
npm start