Serialize to AMF exactly like NetConnection does - actionscript-3

I want to serialize an object to AMF, and I want the result to be exactly the same as if it is serialized by NetConnection.call(). So, I use ByteArray.writeObject(), and the output bytes are usually the same as bytes sent by NetConnection.call(), but sometimes couple of bytes are different.
I found this in AMF3 spec: "Note that ByteArray.writeObject uses one version of AMF to encode the entire object. Unlike NetConnection, ByteArray does not start out in AMF 0 and switch to AMF 3 (with the objectEncoding property set to AMF 3)." It explains that differences.
How can I solve this problem?

The way that NetConnection.call works and how to construct valid requests and responses is documented in detail in the AMF0 specs in section 4. NetConnection.call has some additional functionality, like headers, the RPC method name, and whether or not the request was successful or ran into an error. This is why you can't just use writeObject to create a valid request.
The bit about switching from AMF0 to AMF3 is due to the fact that not every AS3 object can be written without a loss of data in AMF0, but original Flash Players all assumed that the body would be in AMF0. What happens is that during encoding, if you've specified that you want to use AMF3 for encoding, it writes out an AMF0-to-AMF3 marker (0x11) before calling writeObject in AMF3 mode.

Related

Utf8JsonReader from a Stream

I'm trying to read a sequence of JSON objects from a network stream. This involves finding complete JSON objects and returning them one by one. As soon as a complete JSON object was received, I need to have it. Anything else that follows that JSON object is for the next object and must only be used when the next complete object was received.
I would have thought that the Utf8JsonReader class could do that but apparently it cannot accept a Stream of any kind. It even seems to be unwanted to have that possibility.
Now I'm wondering if it's possible at all to use .NET's shiny new JSON parser to read from a stream when I don't know when data arrives and how much of it. Do I need to split the JSON object messages manually or can the already existing reader just stop when it has something and continue when the next thing is available? I mean, if it can do that on a predefined array of bytes, it could surely also do it with some waiting in between until more data is available. That just doesn't seem to be exposed in the public API. Or did I miss something?
The JsonDocument.ParseAsync(Stream) method cannot be used because it would read the stream to the end. That doesn't make sense for a network stream that stays open for a long time and just reads some data from time to time.

Golang sending a response as w.Write vs Render.JSON in Chi Router?

The documentation did not seem to help, and I could not find a lot of post that described the differences in go lang with render.JSON vs a W.Write([]byte). We have a simple chi router that makes a post request and returns the data. I thought the only difference was auto setting content type, but when I use render.JSON it removes the keys.
Can anyone please tell me in a few human words if there is a difference and a good use case to use render vs write? Does anyone have any personal exp, or advice regarding this? I have read the documents, and seen response sent many different ways.
//Current Pref as I can define the headers, etc.
w.WriteHeader(resp.StatusCode)
w.Header().Set("Content-Type", "application/json")
json := []byte(body)
w.Write(json)
//vs (sets content type, but removes the keys* and I am not sure why)
render.JSON(w,r,interface)
See the code for render.JSON. The function encodes the argument to JSON, sets a JSON content type header and writes the JSON to the response. The application can set response headers before calling render.JSON. The application can set the response status by calling render.Status before calling render.JSON.
The ResponseWriter.Write method writes bytes to the response as is.
Note a key difference between render.JSON and ResponseWriter.Write: The former function encodes the argument as JSON and the latter writes the bytes as is.
The render.JSON function encapsulates functionality commonly used by applications. Use the function if you find it convenient.

JSON REST endpoint returning / consuming JSON literals

Is it advisable or not in a RESTful web service to use JSON literal values (string / number) as input parameter in the payload or in the response body?
If I have an endpoint PUT /mytodolist is it OK for it to accept a JSON string literal value "Take out the rubbish" in the request payload (with Content-Type=application/json) or should it accept a JSON object instead ({"value":"Take out the rubbish"})?
Similarly, is it fine for GET /mytodolist/1 to return "Take out the rubbish" in the response body or should it return a proper JSON object {"value":"Take out the rubbish"}
Spring MVC to makes implementing and testing such endpoints easy, however clients have flagged this as non standard or hard to implement. In my point of view JSON literals are JSON, but not JSON objects, so I'd say it is fine. I have found no recommendations using Google.
EDIT 1: Clafirication
The question is entirely about the 'standard', if it allows this or not.
I understand the problem with the extensibility, but one can never design a fully extensible interface IMHO. If changes need to be done, we can try extending what we have in a backwards compatible way, but there will come a time when it becomes messy and an other approach is required - which is commonly handled by versioning the API in one way or another. I find it a fair point even though, because using literals as request/response body immediately becomes inextensible, while coming up with a reasonable one-attribute JSON object does not.
It is also understood that some frameworks have problems with handling JSON literals, this is the origin of this question. The tool I used happened to support this, so I thought this was all right, but the front-end library did not.
Still, what I am intending to find out right now, is if using JSON literals is according to the de-facto standard (even if it is a cornercase) or not.
I would recommend to use JSON object always. One reason is that for Content-Type application/json people expect something staring with "{" and not all frameworks will handle json literals properly. Second reason is that probably you will add some additional attributes to you list item (due date, category, priority, etc). And then you'll break backward compatibility, by adding new field.
It may be acceptable in the context of your example, but keep in mind that unambiguous interfaces are easier to use and that will encourage adoption.
For example, your interface could interpret "Take out he rubbish" as the same as {task:"take out the rubbish"}, but once you add additional properties (eg "when" or "who") the meaning of a solitary string in the request becomes ambiguous. It's inevitable that you'll add support for new properties as your interface matures.

Debugging json4s read deserialization errors

I am attempting to consume an API that I do not have control over which is somewhat poorly documentented and somewhat inconsistent. This means that sometimes, the API returns a different type than what is documented or what you would normally see. For this example, we'll look at a case when an array was returned in a place where I would normally see a string. That makes a crappy API, but my real problem is: How can I more easily track those things down? Right now, the errors look something like this:
No usable value for identifier
Do not know how to convert JArray(List(JString(3c8723eceb1a), JString(cba8849e7a2f))) into class java.lang.String
After deciphering the problem (why JValue::toString doesn't emit a JSON string is utterly perplexing to me), I can figure out the API returned an array when I made my case class only able to deal with Strings. Great. My issue is that finding this discrepancy between my object model and the contents of the JSON seems significantly more difficult than it should be.
Currently, this is my workflow for hunting down decoding errors:
Hope bad data has some sort of identifying marker. If this is not true, then it is way more guesswork and you will have to repeat the following steps for each entry that looks like the bad bits.
Go through the troubles of converting the JArray(List(JString(...), ...)) from the error message into valid JSON, hoping that I encode JSON the same way at the API endpoint I got the data from does. If this is not true, then I use a JSON formatter (jq) to format all data consistently.
Locate the place in the source data where the decoding error originates from.
Backtrack through arrays and objects to discover how I need to change my object model to more accurately represent what data is coming back to me from the API.
Some background: I'm coming from C++, where I rolled my own JSON deserialization framework for this purpose. The equivalent error when using the library I built is:
Error decoding value at result.taskInstances[914].subtasks[5].identifier: expected std::string but found array value (["3c8723eceb1a","cba8849e7a2f"]) at 1:4084564
This is my process when using my hand-rolled library:
Look at the expected type (std::string) compared with the data that was actually found (["3c8723eceb1a","cba8849e7a2f"]) and alter my data model for the path for the data in the source (result.taskInstances[914].subtasks[5].identifier)
As you can see, I get to jump immediately to the problem that I actually have.
My question is: Is there a way to more quickly debug inconsistencies between my data model and the results I'm getting back from the API?
I'm using json4s-native_2.10 version 3.2.8.
A simplified example:
{ "property": ["3c8723eceb1a", "cba8849e7a2f"] }
Does not mesh with Scala class:
case class Thing(property: String)
The best solution would be to use Try http://www.scala-lang.org/api/current/#scala.util.Try in Scala, but unfortunately json4s API cannot.
So, I think you should use Scala Option type http://www.scala-lang.org/api/current/#scala.Option .
In Scala, and more generally in functional languages, Options are used to represent an object that can be there or not (like à nil value).
For handle parsing failures, you can use parse(str).toOption, which is a function that return an Option[JValue], and you can doing a pattern matching on the resulting value.
For handling extraction of data extraction into case classes, you can use extractOpt function, to do pattern matching on the value.
You can read this answer : https://stackoverflow.com/a/15944506/2330361

Can RestSharp handle byte arrays?

I'm using RestSharp. I was using XML as the transport encoding for my data, but then I had problems with that, so I switched to using JSON. Now I'm having problems with that too!
All was well until I tried to pass an object containing a byte array (*). Now I get a de-serialization error complaining about "object has no parameterless constructor". (The JSON returned by the server looks Kosher - it's just not being correctly de-serialized by RestSharp).
I see I'm not the only one having problems. Is there no solution other than the baby-out-with-the-bathwater approach suggested in that post?
(*) I had tested it with a small hand-coded byte array early on in my development, just to check that it worked. It did work then, but doesn't work now. I don't know if that's due to the size of the array, the "characters" in the array, or what. Dammit, this has been such a time-sink!
For anyone else struggling with this, I ended up simply swapping out the JSON formatter in favour of JSON.NET. That works.