Currently I am creating some intra-service calls among microservices. Opting to leverage google's protobuf, I am using it in unison with Spring Boot Rest APIs. And I am presented with two options.
First: Serializing the protobuf objects. It is possible to serialize protobuf objects in the REST request and have the receiving end deserialize it and perform whatever it needs, then serialize a protobuf response for the initial caller. This involves a flow of serializing, deserializing, and vice versa.
Second: Sending the protobuf object as is. It seems like a REST API is able to accept x-protobuf requests. I am wondering if this has any significant drawbacks in terms of speed?
Currently, I am employing the latter, I was wondering if anyone else who has tried this prefers one over the other?
Related
I'm writing a basic SDK for Java & Python (and potentially other languages in the future) consumers of an API (REST as well as message-queue orientated responses).
Instead of maintaining separate per-language descriptions, I was wondering if there was perhaps a way to define classes and enums in something like YAML which could be automatically be converted into appropriate objects in each language.
I imagine I could write the objects in C and then make per-language bindings - but this seems a bit hacky as a solution.
You can use JSON to represent your object model and translate it to objects in each of the language you are using.
Here are some relevant articles that will help you get started.
How to convert Java object to / from JSON (Jackson)
https://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
https://realpython.com/python-json/#encoding-and-decoding-custom-python-objects
Working With JSON Data in Python
Another option is Protocol Buffers though it is not as favorite as JSON when working with REST apis.
Martin Fowler said to avoid automatic deserialization in an API:
I prefer to avoid automatic deserialization altogether. Automatic
deserialization usually falls into the WSDL pitfall of coupling
consumers and producers by duplicating a static class structure in
both.
What this means?
Is it to receive all information as JSON in each Rest Service without any "converter" in the middle?
By "converter" I mean some type adapter, like in GsonBuilder.
By automatic deserialization he means that there's a predefined hard structure for the JSON object which is used to retrieve the object itself.
This is however appropriate for most use cases.
Examples of predefined structure are Java Class or XML XSD.
Automatic deserialization usually falls into the WSDL pitfall of coupling consumers and producers by duplicating a static class structure in both.
What he means here is that using classes for deserialization is same as using WSDL to serialize or deserialize objects.
On the contrary to the hard structure of classes and XSD documents, JSON is much more relaxed as it's based on Javascript which allows modification to the object definition at any point of it's life cycle.
So the alternative would be to use a HashMap and ArrayList in Java combination (or parsing String itself) to deserialize the object, as then even if the server produces something different (like new fields) no change would be needed at the client side. And new clients can take advantage of the new fields.
In a hard structure since both the producer and consumer are strongly coupled because of the shared structure of the model classes, any change in the producer has to be reflected in the consumer.
In some SOA projects where I worked, we used to add some extra fields in all the request/response objects for future use so that there was no need to change the clients running in the production to accommodate the needs of a new client. These fields had some random name like customParam1 to customParam5, where the meaning of these fields was released with the documentation. These names were not intuitive all because we were coupling the producer and consumer on the shared structure or models.
I'm returning to backend development after a few years focusing on iOS. I've chosen Spring Boot with Kotlin.
I would like to have a domain-centric, general, reusable model objects.
For service invocations I would like to return use-cases specific responses where the payload in/out is just the information for that particular scenario. (We can call this "contract-first" or "don't spill your guts")
In the past I might've implemented a service by mapping the information from reusable model objects onto a serializable value object using a framework like Dozer.
Alternatively, I was thinking of registering a custom serializer for a given endpoint, as eg Django Rest Framework does. (Not sure how this would work given jackson serializes by annotations).
Questions:
Is there an easy way to use custom serializers with jackson to do what I want?
Or is it better to continue using the value-object approach I used years ago?
Depending on your use case, using dedicated DTOs could be a good idea. Just so you know, you can get more flexibility from Jackson without implementing custom serializers for each scenario - Jackson Json Views are now supported in Spring MVC and quite useful.
I'd like to create a web API of some kind (I don't have a preference for the protocol), where the server uses Java and the client uses PHP.
I want the request and response to both be objects (instances of classes, not JSON-style hashes). The objects' fields can be primitive types or other objects. I would define all the necessary classes in both the client and server code. PHP and Java have similar object models, so it shouldn't be hard to write corresponding classes in both languages.
To make this work, there would need to be some automated way to serialize an object on one side, and unserialize it on the other. It would need to know which PHP class maps to which Java class, and how to convert the fields. I could write something, but is there an existing protocol for transferring objects like this? Can this be done with SOAP?
Java and PHP objects are not interchangeable. You will have to define the object types on both ends, and the transfer protocol could be anything you like. Serialization and deserialization makes the whole process transparent. The transport medium could be JSON, XML, YAML, or anything else for that matter.
For a record-like objects:
{"_type":"MyCoolObjectType", "a":1, "b":2, "c":3"}
If you're wanting to write once and use everywhere, I'd recommend using the same language on both ends, otherwise you'll have to have a compiler that can translate between your choice languages.
A SOAP web service can handle the basic abstraction as long as the request/response is not very complex. You can create the classes in java and then get the API to export a WSDL for them.
You need to have them both serialize to the same string. The PHP format and Java format for serialization are different, and therefore incompatible. You need a common exchange format, and I recommend that you DON'T use PHP's. However, the functions to serialize in PHP are fairly simple, are contained in ext/standard/var.c file in the PHP source if you choose to use it..
See the following:
Unserialize in Java a serialized php object - A similar question to yours.
http://en.wikipedia.org/wiki/Serialization#Serialization_formats
http://en.wikipedia.org/wiki/XML
XML, API, CSV, SOAP! Understanding the Alphabet Soup of Data Exchange
From http://en.wikipedia.org/wiki/XML (emphasis mine):
Although the design of XML focuses on documents, it is widely used for the representation of arbitrary data structures, for example in web services.
Scenario:
I'm working on a web services project. It supports SOAP and REST. The SOAP request and response are handled by XmlObjects. The REST architectures uses plain POJO's for request and Response. I have a common controller to handle the request from SOAP and REST. This controller understands a common object (Request Object). And , the controller sends back a Transfer Object. In front of the controller , I have a request translator to translate the SOAP/POJO objects to common Request Object. And also a response translator to convert the transfer objects to SOAP/REST view objects.
Problem:
I have 2 request and response translators. The SOAP/REST request and response translators look the same. But, they take a different object as input. So it looks like I have the same code 2 times.
How to avoid this redundancy?
Solutions that I thought of : Bean mapping.
Is there anything else more elegant than this?
I assume both your "REST" and "SOAP" APIs must do the same thing and are therefore quite parallel. You ought to (re)read Roy Fielding's description of the REST architectural approach and then decide if these APIs are truly RESTful in Roy's very precise definition of the term. If they are both RESTful, then just ditch your SOAP APIs: SOAP is harder to use, doesn't leverage HTTP caches, and adds nothing over your REST APIs.
If they are both non-RESTful (ie, they have a Remote Procedure Call flavor and the "REST" APIs just happen to do RPC operations using HTTP and XML), then assuming you can't convert them to the REST architectural style, you can at least factor out the POJO<==>XML mappings using a library like XStream.
You are right, If only the request/response XML differs in layout only and the data is same then you can make XSLTs for both of them which will convert it into proper XML as per your POJO.
Then you can use Castor mapping for XML to POJO object right? And you will get your needed object. But you have to make the object common for the code right?
What i mean is, use common object for your logic and use some another logic to get that object from your Request/Response objects for SOAP/REST. Because the data you are sending will be same in both kind of methods, you just need to handle Object to object conversion. That can be done directly OR using Object to XML and XML to object.depends which you prefer.
hope this helps.
Parth.