REST call may results in two different JSON objects. What design pattern should I use? - parsing

My web application makes a REST call. If the call is successful, it will return a 'weather' json object. If the call fails, it will return a json error object.
I want to make a class that parses the resulting JSON and returns a Weather object if the call succeeded and an Error Object if the call failed.
I'm thinking of using the Factory pattern but I'm not sure if that's a good approach because the two objects are very different from one another. What is a good way to design this code?

A common approach I use is to have Weather and Error both be Response objects and have a ResponseFactory create them.
I strongly encourage you to use proper HTTP codes when designing your service as they give a more general view of the state and success of each call.

You need first to check the result of the call, and then make a decision on how to handle it, with the possibility of handling all error codes with an error callback that returns an Error JSON object, and a success callback to return a Weather JSON object. You can use the HTTP codes to create a proper response and further subdivide the logic to return more specific errors, if needed.
The use of a Factory pattern seems overkill, specially given that the objects don't relate to each other.

It really depends on the environment you'll be using your API.
As a rule of thumb, rely on the HTTP code - if you get a 404 or a 500 of course you can't come up with a parsed response.
Format your error responses in a consistent way, e.g.
404 { "message" : "Resource not found" }
400 { "message" : "Wrong parameters given" }
So you know how to parse them.
If you get a 200 OKyou know everything was right, and you can parse your response with no problem at all.

Does the Content-Type header vary depending on the type of response?
As some have noted in their answers, the HTTP status code should be used to determine "Was there an error", but just as important is the interpretation of the content type returned.
Hoping the Content-Type header does vary, I would suggest using a registry of parsers, registered by content-type they handle, and then delegate to them to handle understanding how to convert a particular content type into the object you want. In Ruby, since you didn't specify a particular language:
case response.status:
when 200..299
return parsers[response.content_type].parse(response.body)
when 400..499
raise parsers[response.content_type].parse(response.body)
else
raise "Unhandled response status"
Doing so separates the two concerns:
Determining if there was an error
Parsing of content types into classes/types in your application.

Related

How to handle tile request errors from ol.source.WMTS - Openlayers 3

By using the obvious event handler::
layer.getSource().on('tileloaderror', function (ev) {
console.log(ev);
});
I get an output rather useless, since it doesn't seem to contain any information regarding HTTP Response body/headers etc.
Is there a way to access those kind of information after a failed tile request?
In my implementation, access token must be updated, thus response code is necessary.
If not possible after all, maybe there is a way to create a custom tile load request (maybe implement my own "tileloadfunction" or something).

IOS/Objective-C/JSON:Obtain single value from Web Service in JSON

I want to obtain a single value from a web service in JSON, just a file name i.e. "picture.png"; based on some parameters passed.
Can IOS (I guess NSJSONSerialization JSONObjectWithData:) handle this single value in JSON or on the server side should I have it send a dictionary key as in {"pic": "picture.gif"}
If there is no picture, I am returning "nopic" so again should I have it return "error" or {"error": "nopic"}
I gather the various JSON specifications are conflicting on this point so my interest is just practical...how best to handle this case.
Thanks for any guidance on this

How can I use results of POST call to API to do another POST call

In a project I am working on, I am calling an https API with a POST request which gives me results as a JSON. I am doing the call with AlamoFire, and parsing this with SwiftJSON.
All goes according to plans, and the JSON is received and can be parsed. But now I want to use the values from the received JSON, and immediately do another call to the same API with a different path and use those values as parameters in the call.
At the moment I am posting a NSNotification and when that NSNotification is received I do the POST call to the other path for the details of the data. This works, but not very consistently.
I think that sometimes the data gets in the wrong sequence and the parameters might not be correct. About 80% of the time it works as expected.
Is this the way to work? Or is this not correct to do it with NSNotification? Any insights on this might help!
If you're using this notification pattern correctly, it should work 100% of the time, not 80% of the time. Or, more accurately, if the network connection or server response fails for reasons outside of your control, you should handle it gracefully. If you need help on that problem, update your question with MCVE and we'll see if we can help you.
In terms of a more efficient way to handle this overall process, the typical pattern would be to initiate the second request from inside the response closure of the first request.
Alamofire.request(.POST, url1, parameters: parameters1).response { request, response, data, error in
// create url2 and/or parameters2
Alamofire.request(.POST, url2, parameters: parameters2).response { request, response, data, error in
// do something with second request
}
}
One would generally only use the notification pattern if there is no reliable relationship between the two processes (e.g. when the first request was initiated, it has no reasonable way of possibly knowing which (if any) secondary request(s) will need to react in response to the first request.

How to safely treat data from JSON when the expected type may differ?

As of iOS 5 and OSX 10.7 and higher it is really easy to parse JSON with NSJSONSerialization, which will return either an NSDictionary or NSArray (or mutable variants, if specified) when parsing JSON. Values are parsed as common Cocoa types such as NSString and NSNumber however I would be interested to know how careful I need to be when taking the data from the NSDictionary or NSArray and parsing it into data objects in my app. My key concerns are whether the key's value a) is not nil and b) isn't of an unexpected type.
For example, assume I had the following JSON object:
{
"version":1,
"title":"Some interesting title",
"info":"Some detail here"
}
Currently, this would be parsed as an NSDictionary:
#{
#"version": #1,
#"title":#"Some interesting title",
#"info": #"Some detail here"
}
My problem is how careful I should be when checking the data types of what I'm getting back. In theory, if I'm using a good API I should always get a numeric value for the version key, but what if for some reason it is changed server side to the following:
{ "version:"1", ... }
Or even worse:
{ "version:"one", ... }
If I attempt the following code, I will get hit an exception and my app would crash:
NSNumber * myNumber = dictionary[#"version"];
if ([myNumber isEqualToNumber:#1])
{
...
}
The code wouldn't execute because a) dictionary[#"version"] would be an NSString and b) isEqualToNumber: is only available on NSNumber (unrecognized selector exception, app would crash).
Equally, problems could arise if the JSON for "info" was changed to the following:
{
"info":{
"code":200,
"message":"Some detail here"
}
}
If my app expects an NSString for the key info it will again crash, because an NSDictionary will have been found instead.
On the large part, most JSON from an API or file should be sound and supported by the current version of the app and one would hope that all JSON is versioned and correctly encoded server side. In some cases, if the JSON has been corrupted or modified, the app could crash, which I want to avoid.
Potential solutions:
Check every single key/value pair for isKindOfClass: or respondsToSelector: and only continue if true
Check the key exists and produce an error if nil
Wrap up everything in a try/catch block, however I would rather what can be used is used and an error is produced if something is wrong with the data. This could end up with a lot of #try/#catch statements inside one another
Each of these solutions is rather bulky and adds a lot to my code which I would prefer to avoid, if possible (and when working with 'good' JSON it is perfectly possible). If there is an alternative solution that will handle the process of parsing JSON, checking keys' type and values before putting it in a custom object I would love to know.
You should generally be running against a stable API. The kind of changes you're worried about should be accompanied by a version number change in any reasonable system which would insulate your app from the change until an appropriate upgrade time. So, you should generally know the data type to expect.
In some cases the API will specify that a dictionary or an array may be received depending on the multiplicity, something like that. In this case you should check the class and act accordingly.
You should definitely check for nil and NSNull and handle those gracefully.
Corrupted JSON should be handled by the parser and an appropriate error returned to you.
Also, you could use a framework like RestKit to do the mapping to your custom objects for you. It does a lot of data type checking as standard and removes basically all of your mapping code into a simple configuration. It also handles all of the network comms (via AFNetworking).
You need to make sure your code is safe against attacks from hackers. When you request JSON from a server, you must expect that the data doesn't come from your server but from somewhere else, and that someone else might have designed the data returned to cause maximum damage. Now just crashing if you receive a string instead of a number is quite secure.
You must expect that your request to the server is instead fulfilled by some brain damaged hardware that tries to be "helpful" for example when an internet connection fails. Instead of JSON you might receive a "helpful" website that is supposed to tell a user how to reset their router. A user trying to use someone's free WiFi may have connections return weird result. That's usually no problem with JSON because the parsing will fail (so failed parsing is something you should expect and handle), more of a problem if you expect html.
You must expect that a public API that you are using has bugs or unexpected behaviour and you should behave well when that happens. Add debugging code that will at least log anything unexpected while you are developing. Write your code so that it works with any behaviour that the API shows.
If you are using your own API, you should also log anything unexpected, and then tell the server people if they do anything they shouldn't.

MVC 4 Web API - CreateResponse(status, object) causes HTTP 500

Does anyone know more about this problem with CreateResponse?
public HttpResponseMessage GetProductLine(Guid id)
{ ... // get object etc. //
// This works.
return this.Request.CreateResponse(HttpStatusCode.OK, productLine);
// This causes HTTP 500 Internal Server Error.
return this.Request.CreateResponse(HttpStatusCode.OK, (EntityObject)productLine);
It creates the response but something goes wrong when it is returned, so within the Web API framework.
I discovered this because I have a base API controller in which I have my own CreateResponse method which calls this.Request.CreateResponse as per above, then adds a few headers and writes some logging to the response and hands it back.
What's particularly interesting is that this works for one of my entity controllers, and not for this latest one - i.e. it just doesn't like some entities.
I can solve it by making my implementation look like this:
MyBaseApiController.CreateResponse<T>(HttpStatusCode statusCode, T entity)
where T : EntityObject
But nevertheless, it is odd.
UPDATE
Due to some DRY refactoring, my previous fix is broken. I cannot figure out how to con it into working again, so I'm stuck.
The problem does not seem to occur when returning objects from the database but when I return an object that has been received in a Put.
The problem also occurs when building my own HttpResponseMessage manually and setting the formatters.
I'll have to re-read the data from the database before returning it and hope that works - my Get is fine, so it should do.
UPDATE 2
Oh that's insane. Even if I get the object again from EF and return it using the same line of code as in my Get handler/action, it fails. The difference now must be in the requests - the GET formed by Chrome is fine, the PUT formed by my test client (JSON) must be tripping it up.
UPDATE 3
I spent the day flattening out my entities to avoid any inheritence and the problem has gone. Inheritence is a no no, it seems.
UPDATE 4
So I have a new WebAPI service which is returning a serializable class I've written. Although it can be serialized using the DataContractSerializer, when my request accepts XML I get a 500 but its fine when I accept JSON.
UPDATE 5
Using an ITraceWriter I've managed to see the stacktrace, which ends like this:
Exception.Source: System.Xml Exception.Message: '', hexadecimal value
0x05, is an invalid character. Exception.StackTrace: at
System.Xml.XmlUtf8RawTextWriter.InvalidXmlChar(Int32 ch, Byte* pDst,
Boolean entitize)
Looks like some byte arrays in the object are screwing with the Xml formatter/serializer.

Resources