DEV Community

David
David

Posted on

What did you learn this week?

For example, I've learnt that a green test written in the past might be a false positive test today.

Oldest comments (2)

Collapse
 
nhkk profile image
NHKK

It’s extremely painful to refactor code with no tests, no docs, and no history of its requirements

Collapse
 
russcoder profile image
RussCoder • Edited

I found that json rpc 2 is a much better protocol for inner API for admin dashboards. It's much simpler than REST, it's very clear.

I don't have to think how to call an endpoint according to the "REST rules", I don't have to bother about http cache, since all requests are POST, and using a proxy object on the client I can easily implement an interface looking as if I call a server-side method directly, e.g.

On the server:

const apiMethods = require('./innerApi');

app.post('/api/jsonrpc2', async (req, res) => {
    const data = req.body;
    try {
        if (!apiMethods[data.method]) {
            return res.send({
                id: data.id,
                error: { message: `No method "${data.method}"` },
            });
        }

        const result = await apiMethods[data.method](data.params);
        return res.send({
            id: data.id,
            result: result,
        });
    } catch (e) {
        res.send({
            id: data.id,
            error: { message: "Unexpected error. Message: " + e.message },
        })
    }
});

On the client:

let id = 1;

export const rpc = new Proxy({}, {
    get(target, prop) {
        return async (params) => {
            const data = await fetch('/api/jsonrpc2', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    jsonrpc: '2.0',
                    method: prop,
                    params: params,
                    id: id++,
                })
            }).then(r => r.json());

            if (data.error) {
                throw new Error(data.error.message);
            }
            return data.result;
        };
    },
});

And then I can just add a method on the server and call it on the client:

const result = await rpc.anyServerMethodHere(params)

which is very handy.