I've been using both this SDK and the NodeJS SDK extensively for a few months now, and I've found that the SDKs are much easier to use when API calls are promise-based. I've been using a wrapper function that provides this functionality, which works fine but is not ideal. That looks something like this (shortened for brevity)
function playfabAPI(endpoint, requestObject) {
return new Promise(function(resolve, reject) {
PlayFabClientSDK[endpoint](requestObject, function(error, result) {
if (error !== null) {
// Request error
return reject(new Error(error));
}
else if (result && result["code"] == 200) {
// Request successful
return resolve(result);
}
else {
// Non-200 HTTP status
return reject(new Error(result.status));
}
});
});
}
This makes for cleaner code, adds useful functionality, and eliminates a lot of redundant error checking code. The current request functions are consistent enough for this to work in most cases so far but I'm a bit wary of using it in production. What I would propose is to implement this either alongside the current format, or as an additional SDK/script, for compatibility reasons.
Example of how this change could be implemented in a given function:
Current
exports.UpdateUserData = function (request, callback) {
if (PlayFab._internalSettings.sessionTicket == null) {
throw "Must be logged in to call this method";
}
PlayFab.MakeRequest(
PlayFab.GetServerUrl() + "/Client/UpdateUserData",
request,
"X-Authorization",
PlayFab._internalSettings.sessionTicket,
function (error, result) {
if (callback != null) {
callback(error, result);
}
},
);
};
Proposed
exports.UpdateUserData = function (request)
{
return new Promise((resolve, reject) => {
if (PlayFab._internalSettings.sessionTicket == null) {
throw "Must be logged in to call this method";
}
PlayFab.MakeRequest(
PlayFab.GetServerUrl() + "/Client/UpdateUserData",
request,
"X-Authorization",
PlayFab._internalSettings.sessionTicket,
(error, result) => {
if (error !== null) {
return reject(new Error(error));
}
else if (result && result["code"] == 200) {
return resolve(result);
}
else {
return reject(new Error(result.status));
}
},
);
});
};
Example usage of current vs proposed usage:
Current
PlayFabClientSDK.UpdateUserData(requestParameters, function(error, result) {
// Check for + handle errors...
// Handle result...
});
Proposed
PlayFabClientSDK.UpdateUserData(requestParameters).then((userDataResult) => {
// Handle userDataResult...
}).catch((error) => {
// Handle errors...
});
This would also have the added benefit of allowing the use of async/await which can greatly simplify code structure, e.g. when chaining requests
(async function() {
const userDataResult = await PlayFabClientSDK.UpdateUserData(requestParameters);
// Handle userDataResult/make additional API requests
})();
Let me know what you guys think. Is this something that would be better served using the SDK generator with a custom config, or would it be feasible to get an official implementation?