This isn't a script at all but a way to call an RPC method. And over a non duplex connection at that.
I often use something very similar with a few additions to support callbacks. Add an ID field so that responses can be matched and you suddenly support calls being made over a duplex connection such as Websocket or TCP connection;
Shorthand and longhand formats complicate things so stick with one type. The whole $ prefixed params are also un-needed, especially if your'e expecting them and have the important values under your own expected keys anyway.
But then after all this you start turning into json-rpc.
JSON-RPC allows simple batching but it doesn't allow any server side logic between calls. Individual calls to external instructions in JSONScript are indeed similar.
The full syntax can be used if you need to evaluate some of the fields, it's also easier to parse. Short syntax is implemented as a macro - it's expanded to full syntax before evolution. Given that it in most cases short syntax is better I was going to hide full syntax a bit...
Re '$', there is no expectation on the location of the script instructions in the object structure, unlike JSON RPC. So it is used to differentiate instructions from simple data structures that can be part of the script.
This exact concept has been done multiple times. And it never worked, because the syntax was horrible. And it's just not convenient at all, it's good for toying around with interpreters and the likes but it has no purpose or use. See https://m.reddit.com/r/coding/comments/3akmn1/sums_this_rel_...
This reminds me of my multiple attempts in writing a declarative scrapper framework. In the end, I've chosen to just write the code.
What I see is a crappy ad-hoc scripting language. I feel bad saying so, but I can only view this project as a bad solution to whatever problem you have.
You could have chosen to send actual code, be it JavaScript, Python, Java or even Linux binaries, executed with limited privileges. How would that look like? AWS Lambda.
Sending code in some existing general purpose or scripting language makes it either difficult/inefficient to parse, or insecure (if, e.g. JavaScript or bash eval is used), or both. Limited privileges only partially protect the host and usually leave some vulnerabilities...
JSONScript is both very easy and efficient to parse (a JSON-Schema is used to evaluate the script) and it is secure because it executes the script in a "sandbox" having access only to those system resources that the host environment explicitly exposed to the interpreter.
My two main use cases are 1) scripted processing on top of existing API (implemented) and 2) proxy allowing scripted processing across multiple APIs in the same location (soon).
I still don't understand how this has any security advantages over just sending code. You are sending code, just shoehorning it into a serialization format.
The difference is that general purpose programming languages usually provide full access to the host environment, they are not designed to be received from untrusted environments.
You need to reduce what is allowed, and that is more likely to leave vulnerabilities, than explicitly whitelisting what methods can be called.
I think that any abstraction/DSL, not JSONScript specifically, with a specialised interpreter on the server side is more likely to be secure than processing general purpose language instructions received from the client.
It's funny that I've always been annoyed myself that I need to click around to find the language sample all the time, and yet I've put all the examples on the Langauge page (http://www.json-script.com/language.html). Thank you for the suggestion, I will add some example to the home page.
I like the problem you are trying to solve and I like the idea of the JSON data structure but I am not so keen on the language as JSON. I find it hard to read, which would be worse in more complex real-world examples.
I guess I would like to see the code as plain text. Packaging all the data to send as JSON is OK, and the code could be text in a single JSON data element.
Post a story to Hacker News once you get some experience using JSONScript with some feedback on how you went and how the idea evolves.
This technique never ends well. When your service interface is some untestible semi-script language your clients will hate you.
Nice work on building an interpreter, but I'd throw the entire SOA book at you for deploying this in a production environment. I haven't even addressed stability, latency and load of programmable Web interfaces, or security.
I agree that this isn't an SOA architecture. I see this more like an SQL stored procedure where you want to get simple code closer to the data for performance and efficiency.
I would like to see some use case thoughts about where this would work better than other alternatives.
Thank you. One use case that's already working is an express middleware - allows you to bold on JSONScript on existing express ap in a single line of code. Another is a proxy to manage batch processing across multiple services - going to make it.
Joking aside, why do you think it is any more untestable than any other batch endpoint out there? The concerns you are listing are all valid and can be addressed.
They can be addressed, but you'd have to address them anyway with a simpler interface and it would be less work to do so.
This is more untestable because the service that provides the scripting interface needs to have a test bed that is similar to the test bed of an entire language itself. Are there corner cases? Can a client cause a script to loop indefinitely? Is there a test case for every known combination a client would attempt? If so, why not just support each use case explicitly?
There are 1000 reasons why being additionally clever causes more headaches than its worth. I'm not too upset about it - because I'm confident those that don't heed this warning will learn the lesson the hard way.
I think it's a cool proof of concept and you tried out a bunch of ideas that could work, but I don't think you should use this approach for anything. JSON is not conducive for encapsulating complex logic, and it shows. Who is going to write and maintain that spaghetti code? Anyway, code execution at the datasource, is not a new problem, and there are approaches to solving it. Redis for example allows you to upload and execute Lua scripts at the source - way easier, way more readable, makes infinitely more sense. So why not use Lua or just use JavaScript - since your front-end code is all JavaScript anyway?
Redis's implementation of Lua is extremely limited, and even then there is no easy way to validate the script apart from sending to the server. JSONScript can be simply validated against the JSON-schema, no execution is required to check it's validity.
I see this solution as server-side script processing on top of existing REST API(s), as I wrote below. Using Lua for this purpose is possible I guess; but I want the solution that is easy to implement, extend and maintain.
And I am happy to write and maintain this code; whether it's "spaghetti" depends on the way it is written, as for all languages.
Thanks for all the comments, some are really useful. JSONScript is an interesting experiment and the time will show whether it's useful and whether we use it. What I find really interesting is why most higher level abstractions that reduce the amount of code to be written polarise normally friendly people to such extent, and "just writing code" is seen as the only "sane" choice. On the other hand, tools that increase the amount of code are usually very welcome. Any idea why it is happening?
I don't think the intention is to "increase the amount of code" but that's what always ends up happening! You're definitely on to something here with JSONScript but it's missing "something". That killer feature that immediately indicates to the developer/end user, "Yeah, that could definitely make my life easier."
I've implemented something similar with my own projects in the past and I think others have and ultimately will as well. "What problem causes us all to ultimately implement something like JSONScript or JSON RPC?"
I think there's two problems and I think JSONScript went a bit too far/got too specific as to how to solve them:
1) How to specify (multiple) destinations when delivering API requests and their order of execution.
2) How to execute actions safely despite potentially dangerous payloads.
I suggest removing the "path" part as it can easily be included in the top level of the object (e.g. {"someapp: destination": "payload here"}. I also suggest removing the "get" and "put" nomenclature. That's so old fashioned and synchronous :) . Shouldn't such things be determined by the destination functions?
That is indeed a valid concern. I thought about an option to limit the evaluation time and the memory used. Although I don't think it's possible at the moment to request something that would cause an endless loop. There are no loops (yet), it can only iterate arrays (can be large, but limited), and I did not plan to support recursive function calls. Denial of service is also a valid concern when you handle individual requests (although the solutions for it exist).
Interesting. I saw GraphQL; I thought that given that it's query language it won't have this problem... Although if you'd exposed SQL it would have been super easy to kill the server. I am about to start using JSONScript for internal apps/services we have, where DoS is not a concern. For the public usage it needs some improvements to implement the limits I mentioned.
I should have said the implementations of GraphQL have similar problems. Since it's just a query language you can implement your own server with limits. Facebook is ultimately just punting on this problem but the declarative query boundary is helpful. Your DSL is much more imperative. You're in a very practical niche between individual ad-hoc endpoints and a completely new way of doing things (GraphQL). Especially for use with existing systems. There are a lot of people out there (at least one) who just want batching and don't need a new abstraction. They know exactly what requests they want made; They just want them to be made on the server. That being said I think you should change your presentation. The thing that's "not right about this", as mentioned in another comment, is that it seems to be a programming language and not a web development tool. It is a programming language but that's incidental to it being a web development tool. I think your scope is in danger of creeping towards a turing-complete homo-iconic scripting language based in JSON. There is something not right about that. Lol. It's a scripting language with syntax derived from the object literals of another scripting language which was in turn syntactically perverted in order to attract the users of non-scripting languages. It's an abominable version of lisp.
Lol. Thanks for the suggestion about presenting it, I need to think about it. "A niche between individual endpoints and completely new way of doing things, batching without new abstraction" - seems like a good way to position it indeed.
You know that feeling you get when a series of completely sensible choices in themselves have somehow led you to a point that - if you could step back and take in the whole picture - would strike you so very clearly as a rather bizarre place to end up...
It's very late here and I'm tired so I can't come up with anything especially constructive but something doesn't feel right about this.
This isn't a script at all but a way to call an RPC method. And over a non duplex connection at that.
I often use something very similar with a few additions to support callbacks. Add an ID field so that responses can be matched and you suddenly support calls being made over a duplex connection such as Websocket or TCP connection;
Shorthand and longhand formats complicate things so stick with one type. The whole $ prefixed params are also un-needed, especially if your'e expecting them and have the important values under your own expected keys anyway.
But then after all this you start turning into json-rpc.