Thursday, December 10, 2015

Aurelia - faking my service layer

In this new application, I am leveraging APIs that don't exist yet. But I don't want to have to re-code my client code once the API is done. Since I know what the API will look like, I can build the call from the client into the service layer, and just make a fake call. Since I want the asynchronous behavior of an AJAX call, I will return a Promise, just like I will get from the real API call once it's done.

I take the same parameters, and I return a Promise that resolves with the same shape of data the API will someday return. An example:
export class Service {
    getDataFromServer(key) {
        return this.makeFakeServiceCall((accept, reject) => {
            accept('Data from server');
        }, 1500);
    }

    makeFakeServiceCall(action, delay) {
        this.awaitingResponse = true;
        
        return new Promise((accept, reject) => {
            setTimeout(() => {
                this.awaitingResponse = false;
                action(accept, reject);
            }, delay);
        });
    }
}
The idea is pretty simple. makeFakeServiceCall accepts an action which will implement the promise resolution and how long in milliseconds to hold the promise. Then, in the action, I can call accept() or reject() as needed to simulate the behavior I want. When it's time to replace with a real service call, I just take out the body and replace it with the call, something like:
    getDataFromServer(key) {
        return this.makeRealServiceCall('get', 'url', key);
    }
Where makeRealServiceCall uses the fetch client to call the API. My implementation of makeRealServiceCall wraps logic about the fetch client and issues a request, unwrapping the json response if there is one. So it returns the resulting data, just like makeFakeServiceCall. One last thing. The flag this.awaitingResponse is used to allow me to implement a common flag for both the fetch client (real API calls) and the fake calls. I have a little method:
    get inServiceCall() {
        return this.awaitingResponse || this.fetchClient.isRequesting;
    }

No comments: