routing-controllers-openapi icon indicating copy to clipboard operation
routing-controllers-openapi copied to clipboard

Testing code for stdin/stdout requests

Open Downchuck opened this issue 5 years ago • 1 comments

This code is something I'm using as part of testing -- it reads JSON from stdin and writes responses back to stdout. The parent routing-controllers project has createExpressServer, but this project has the added decorations to make this more useful.

Using an OpenAPI decorated class:

  const service = new api.Fetch();
  const crypto = require("crypto");
  const stream_in = process.stdin;
  const stream_out = obj => process.stdout.write(JSON.stringify(obj));
  const input = () => handle_input({stream_in, stream_out, service, crypto});
  stream_in.on("readable", input);
  stream_in.resume();

Splitting up input and parsing it as JSON; note the decorator is not used, as this code is incomplete (just calls one method as implied by the default):

function handle_input({stream_in, stream_out, service, crypto, operationId = "Fetch.fromCode"}) {
  let chunk;
  const MALFORMED_INPUT = { error: true, message: "MALFORMED_INPUT" };
  while ((chunk = stream_in.read()) !== null) {
    try {
      let obj = JSON.parse(chunk);
      if ("code" in obj) {
        let requestId = crypto.randomBytes(3*4).toString('base64') ;
        handle_output({requestId});

        (requestId => service.fromCode(obj.code)
          .then(output => handle_output({...output, requestId}))
          .catch(output => handle_output({...output, requestId}))
        )(requestId);
      }
      else handle_output(MALFORMED_INPUT);
    } catch (e) {
      console.error(e);
      handle_output(MALFORMED_INPUT);
    }
  }
}

This was for ease of use, so I can just write {"code": "str"}.

If the API has or needs headers then the combination of nock.back JSON, node-mocks-http and createExpressServer works pretty well.

Downchuck avatar Mar 11 '19 03:03 Downchuck

tighter version with a json parsing package; shutdown function and MALFORMED_INPUT left to imagination.

  // ctrl+c
  process.on("SIGINT", shutdown);

   // ctrl+d
  process.stdin.on("end", shutdown);
  process.stdin.resume();

  // stdin
  const crypto = require("crypto");
  const {createParser} = require("json-stdio");
  const service = new api.FetchPdb();
  process.stdin.pipe(createParser()).on("data", data => {
    const { operationId = "FetchPdb.fromCode" } = data;
    const { requestId = crypto.randomBytes(3 * 4).toString("base64") } = data;
    const write = data => output({ ...data, requestId });
    write({ requestId });
    const {code = ""} = data;
    if(code.length) service
      .fromCode(code)
      .then(write)
      .catch(write);
    else write(MALFORMED_INPUT);
  });

Downchuck avatar Mar 21 '19 02:03 Downchuck