4 ms·
Maybe I just don't get it, but this design seems impractical for systems that use the network alot. I work on an app whose basic structure is 1. Receive data
by 8192kjshad09- 6y ago
Maybe I just don't get it, but this design seems impractical for systems that use the network alot.
I work on an app whose basic structure is
1. Receive data from a webhook (not controlled by me)
2. Make some HTTP requests based on data from 1
3. Send data to another HTTP API
The core of the logic is in step 2. How can I possibly have a functional core here? Step 2s behavior completely depends on the HTTP responses.
- bigmanwalter 6y agoPardon my pseudo-JavaScript, but given an event handler like this: const handler = ( message, data, req=superagent.post ) => { if (message === “a”) return req(“/api/a”, data) if (message === “b”) return {label:”b”, value: req(“/api/b”)} } By supplying the http client using the default argument on line 4, the client can be replaced when testing with a mock handler: test(“handler requests /api/a”, t=> t.assertDeepEqual( handler(“a”, {b:”c”}, (url, body)=>[url, body]) [“/api/a”, {b:”c”}] ) ) test(“handler requests /api/b”, t=> t.assertDeepEqual( handler(“b”, {b:”c”}, (url, body)=>[url, body]) {label:”b”, value:[“/api/b”, {b:”c”}]} ) ) You could also write test cases that handle multiple steps, complex transformations, and so on. It’s really nice being able to specify plainly the inputs and expected outputs of your functions and testing against that! It may not guarantee that everything behaves as the real system but it will catch 100% of your logic errors.
- sidlls 6y agoHardcore test-all-the-things people would likely tell you to break whatever is in step 2 up into functions such that the webhook data are passed as parameters into a function, that all the HTTP request/response work is encapsulated into a separate function, and that the function under test should make calls to these. Really hardcore ones might even suggest having separate functions for all these things, each of which can be tested as a single unit. These people are, in my view, making a categorical error (that more testing of this sort means higher confidence and better quality code).
- jzoch 6y agoThe idea is that your server handler mimics those steps and contains all the IO you need (aka external depdendencies). The receiving and sending of the http requests + any other I/O you need should be immediately visible in the top level method (in a simple model). Everything below is functional and pure. Take a request, use pure functions to transform and reshape the data, pass that back up the call-stack to the top level method. Do some I/O operation against the database, go into functional land to shape it a bit, bring it back up, combine with other data in a pure way and then finally send the response.