ajv-validator / ajv-cli

Command-line interface for Ajv JSON Validator
https://ajv.js.org
MIT License
264 stars 67 forks source link

Accept data on stdin #32

Open handrews opened 7 years ago

handrews commented 7 years ago

The most common way I've noticed many people do casual testing of API responses is with curl. In particular some back-end devs really prefer the command line, which makes ajv-cli great for this purpose. Would it be possible for ajv-cli to take the data JSON from stdin so that

$ curl -X PUT "https://api.example.com/foos/506e3185e9c882d175a2d0cb0093d9f2" \
       -H "Content-Type: application/json" \
       --data '{"id":"506e3185e9c882d175a2d0cb0093d9f2","bar":"1234"}' \
       | ajv validate -s foos-response.json

works? And likewise for ajv test. This of course is more to allow people to poke at things with minimal setup than something intended for a large scale test automation / CI system.

epoberezkin commented 7 years ago

I like this idea, PR is welcome ;)

handrews commented 7 years ago

I'll look into it :)

handrews commented 7 years ago

@epoberezkin getting back to this now. There are several npm packages for working with stdin.

From least to most complex:

Do you have a preference? The middle one seems to have a nice level of functionality, but I do not have strong opinions on this (or a thorough knowledge of any node-specific design choices involved here).

epoberezkin commented 7 years ago

@handrews Simple get-stdin looks the best. Quite some refactoring here to make ajv-cli async. But there is no way around it...

epoberezkin commented 7 years ago

By the way, you should already be able to do something like:

ajv -s schema -d /dev/stdin

to consume data from stdin. Some caveats here though: http://stackoverflow.com/a/5794483/1816503

epoberezkin commented 7 years ago

also see https://unix.stackexchange.com/questions/16990/using-data-read-from-a-pipe-instead-than-from-a-file-in-command-options

handrews commented 7 years ago

@epoberezkin thanks! I'll look through all of this. I'm on-board with using get-stdin.

n1ywb commented 7 years ago

@epoberezkin use bash process substitution; it connects the stdout from the subcommand to a fifo or named pipe and substitutes in that path. e.g.

$ ajv -d <(echo null) -s <(echo {}) 
/dev/fd/63 valid

see also http://tldp.org/LDP/abs/html/process-sub.html

samestep commented 4 years ago

Ran into this today; ended up just writing my schema and data to files first and then using ajv with those explicit filenames. This would definitely be a nice feature to have!

@n1ywb that would be great if it worked, but for some reason it doesn't seem to:

$ ajv -d <(echo null) -s <(echo {})
error:  ENOENT: no such file or directory, open '/proc/4839/fd/pipe:[60837]'

At first I thought the issue was because I had installed Node as a snap, but it persisted even after I uninstalled Node and reinstalled it from apt via NodeSource. Seems to be related to these two Node issues? The same thing happens when using pipes and /dev/stdin instead of process substitution:

$ echo {} > schema.json
$ echo null | ajv -d /dev/stdin -s schema.json
error:  ENOENT: no such file or directory, open '/proc/5717/fd/pipe:[70865]'
epoberezkin commented 3 years ago

Not exactly what's asked here, but related: v4 added a way to write compiled validation code to stdout (e.g. for formatting)

zanerock commented 3 years ago

Not sure this adds anything, but here's my variation. In theory, these calls should have the same result, but they don't.

> ajv -s audits-spec.schema.json -d audits.json --errors=text
audits.json invalid
data/accounts should be string
> ajv -s audits-spec.schema.json -d <(cat audits.json) --errors=text
/dev/fd/63 valid