jansupol / jsonbapi

0 stars 0 forks source link

How is this different from JEE7 javax.json? #51

Open jansupol opened 7 years ago

jansupol commented 7 years ago

There already is a Json api from jee7. What is new in this one, why couldn't the implementation be done based on that API?

Many devs already don't understand how to handle Json in Java. You see a lot of mess, apps using both the standard api and gson from Google or other libs. I really don't see the use for a new one -- but, again, I may be missing something.

jansupol commented 6 years ago
jansupol commented 7 years ago

@moghaddam Commented Hi @amihaiemil

The API you mentioned is the Java API for JSON Processing or JSON-P. It's a more low level API that is mostly used to parse the JSON file. The Java API for JSON Binding or JSON-B is a more higher level api which is used to serialize/deserialize an object into/from JSON format. You can use it to convert a POJO to a JSON string or deserialize a JSON string into a POJO.

As an example the reference implementation of the JSON-B (Yasson) uses JSON-P internally to generate the JSON output based on given input object and vice versa.

Regards

jansupol commented 7 years ago

@amihaiemil Commented @moghaddam I see, thanks for explaining. Will it work with annotations as well, like Jackson does, or just with POJO/getters and setters convention?

jansupol commented 7 years ago

@moghaddam Commented Yes, it works by default without any annotation. You can customize the serialization/deserialization process via annotations.

jansupol commented 7 years ago

@amihaiemil Commented I would like it to work only with annotations, no getters and setters. Pojos are Java's biggest failure. They are the reason we have classes with 80k lines :(

jansupol commented 7 years ago

@amihaiemil Commented @moghaddam @m0mus I am trying to run some examples with the annotations and this does not seem to work:

/**
 * Student from XML.
 */
public XmlStudent implements Student {

    private XML student;

    //ctors

    @Override
    @JsonbProperty
    public String firstName() {
        return this.student.getElement("firstName");
    }

    @Override
    @JsonbProperty
    public String lastName() {
        return this.student.getElement("lastName");
    }

    //....
}

So I would like it to work without getters and setters, no dumb POJOs.

As I understand from this example, @JsonbProperty's role is only to customize the name (key) of the value in the Json?

Please, tell me it isn't so :((

jansupol commented 7 years ago

@amihaiemil Commented I wrote an article today, containing my thoughts about it: http://www.amihaiemil.com/2017/07/04/yasson-yet-another-POJO-parser.html

If we drop the POJO concept, which we should, I think most things can be done with JSON-P :)

jansupol commented 7 years ago

@moghaddam Commented As you know, we have two different standard APIs to deal with XML: JAX-P and JAX-B. They're not for the same purpose and they're not in the same level of abstraction. The JAX-P is targeting the low level XML processing while the JAX-B is a higher level API designed to marshal/unmarshal POJO into/from XML. The same is true about the JSON APIs. The JSON-P is to process the JSON document to generate JSON or read a JSON string while the JSON-B is a higher level API that would be used to serialize/deserialize POJOs into/from JSON string. I think we can't say the JSON-B is another JSON parser API because it's not.

Also regarding your complains about POJOs, if you want to use your POJO just as a placeholder to keep your data and there is no other business in it, then you don't have to define getter/setter methods. It would be enough to just define your properties as public. All APIs mentioned above work perfectly with a POJO with public members and can easily serialize/deserialize them.

jansupol commented 7 years ago

@amihaiemil Commented Well, a really good improvement would be to make the JsonbProperty annotation act like I described in the article.

I am not interested in creating objects from Json. You can have a JsonObject behind an object just fine. String -> JsonObject and then encapsulate that and read from it.

I am interested in creating Json from objects. Real objects, not data holders with String attributes. My object may take data from an Http endpoint (it would encapsulate an http request) and I want Yasson to parse it via that annotation. No ''get'' prefix either. It would really be a step forward towards cleaner OOP.

jansupol commented 7 years ago

@amihaiemil Commented @moghaddam May I open an issue about it? Would you consider implementing that behaviour? (I'm not sure how easy is the process of editing the spec)

jansupol commented 6 years ago

@grimly Commented @amihaiemil I'm unsure why you would serialize a HTTP request. Nevertheless you could use @JsonbTypeSerializer any time you want a special serialisation process. But keep in mind that won't change much from only using Json-P features.

For you get/setterphobia you could take a look at Lombok, it helps a lot at completing the useless code you never want to write.

jansupol commented 6 years ago

@aguibert Commented @amihaiemil it's worth pointing out that getters/setters are not necessary if the fields are public. You could simply have this data class:

public class Student {
  public String firstName;
  public String lastName;
}

And then you could deserialize the object like this:

Jsonb jsonb = JsonbProvider.provider().create.().build();
Student s = jsonb.fromJson(new FileReader("inputs/student.json"), Student.class);

IMO this is a significant improvement over the JSON-P API which can basically only turn JSON data into a glorified Map. Being able to go a step further and get the JSON data into a proper POJO is convenient.

jansupol commented 6 years ago

@amihaiemil Commented @aguibert Lord, no, this is not about getters/setters as boilerplate code! It's about the fact that a POJO is a dumb bag of data, it knows nothing, it is merely syntax sugar. It has the exact same power as a naked JsonObject, just that it's easier for us to read.

Instead, objects should be "live", they should animate the data they have behind, not be the data. E.g. For turning Json into Object, JSON-P is enough:

Student s = new JsonStudent(
    Json.createReader(new FileReader(...)).readObject()
);

However, JSON-P cannot turn Object into Json, and this is why I opened this issue. I would like JSON-B to be able to do that without the POJO concept. Jackson does it just fine, with annotations. Here is a live ElasticSearchResult, which can also be turned into Json thanks to Jackson (SearchResult interface is annotated).

Now, of course, that JsonStudent of mine is not much different from a POJO, but it can be wrapped in decorators and be enriched with functionality. I wrote about it in detail here:

http://www.amihaiemil.com/2017/09/01/data-should-be-animated-not-represented.html

jansupol commented 6 years ago

@amihaiemil Commented @m0mus Well, I got an answer to my initial question, I understood the difference between JSONP and JSONB. Now it's rather a question of whether JSON-B will allow marshalling via the @JsonbProperty("") annotation.

I would like to annotate an object's accessor methods with @JsonbProperty and turn it into Json, but without having to have the get prefix on those methods! And it should also work if the annotation is on an object's interface rather than the class. At the moment, the annotation only dictates the key in the JsonObject, but the method still has to be prefixed with get.

jansupol commented 6 years ago

@gembin Commented Why JSONB doesn't have something like JAXB @XmlAccessorType(XmlAccessType.FIELD) ?