I am in the process of building a REST api which accepts a set of arguments, processes it and gives a boolean response.
My question is how do I build a dto object. I can create a Java POJO in one of the applications and use it as REST parameter but that creates a dependency on this application.
Is there a better way to pass an object as REST parameter?
note: the reason I am not using path params because my dto object might contain a list of objects as well and I am not sure how to pass that using path param.
You can create a library which contains the DTO class if dependency is your concern.
After all the DTO is dependent on the REST API. If one changes the other must change too.
Related
I'm not talking about using the REST classes, like #Path or #POST.
I'm talking about how to translate any REST definition into a model of classes - A model from which many things can be done, like generating client code or parsing incoming data.
A bonus might be to parse an existing Resource class and create the model for it's REST API.
Example of such class might be Resource. A resource must have a path. A resource would have methods, like GET or POST. Methods would have params. And so on...
Methods can be different by definition, for example A POST method can have a stream of data, whereas GET cannot.
So, how to model a REST implementation using classes?
You might find this post interesting : http://dalelane.co.uk/blog/?p=1871
It generates HTML file with an entry for each of a REST end-point in a specific path.
I'm reading the two introductory articles about bulding and consuming Spring Rest web services.
What's weird - they're creating a Greeting representation class in the client app (second link ref) for storing the GET response (the greetingmethod on server side returns a Greeting object). But the Greeting classes on the server and client side are different classes - well, they are two distinct classes with identical names, identical field names and types (client's doesn't have a constructor).
Does it mean I have to similarly rewrite the class from stratch when building the client app? In order to do that, I'd need specs on what are the fields' types of JSON-packed objects passed by server's app. A server serializes the object of class ABCClass to JSON and sends it to client. Even if some field called 'abc' has value 10, it doesn't make it an integer. Next time it might contain a string.
My question is - how much information from server app's devs do I need in order to create a client application? How is it usually done?
It all depends on your deserializer and on your needs. With Jackson for example you might use mixins (wiki ref) and custom deserializers (wiki ref) that build your object with your required field names and your structure.
Its just simplest way to have same field names and structure, but not the only one.
Of course, however, you should know the server reply structure to deserialize it anyway
We have a system that uses http POST with JSON as an RPC method.
It is an in house solution for internal components communication.
The requests and responses are described each by a Java bean (POJO).
My question is, how can I use swagger annotations to create nice documentation in the swagger standard?
I am not afraid from messing around with existing code, but I was wondering if anyone has some experience with something similar.
The goal is to use Swagger UI to display nice docs and give a playground for users to invoke the Apis.
Based on the comments above, it's impossible to describe this sort of API using Swagger. The Swagger specification is intended to REST-based APIs, where the URLs serve as a unique endpoints to describe an operation, and not the payloads.
By definition, Swagger considers a unique operation to be the combination of a URL and the HTTP method (there are requests to expand the definition to include the mime type as well, for example, but it is not currently available).
There is simply no way to describe a single endpoint that operates multiple requests types, each having its own output.
There may be a solution for what you request in the future, but it is not in the near future, not will it answer your requirements to the fullest.
To be clear - this is not an issue of messing around with code or anything. The specification itself doesn't support it.
There are 2 simple tweaks required to make a swagger file work for any generic hand-built RPC application.
The first tweak is to make the swagger endpoints appear to be unique. This is done by defining each endpoint with a unique name after a hash in the context. This works because your app will not process the url past the '#' and this allows swagger to consider the path to be "unique". In reality though this technique will allow every unique path defined in the swagger file to actually invoke the same endpoint.
paths:
/endpoint#myUniqueCommandA
...
/endpoint#myUniqueCommandB
...
The other tweak is needed to ensure the generated swagger clients will actually call the correct operation inside your RPC app. This is done by implementing a "defaulted single value" enum in each command's request object. The defined enum represents the corresponding attribute / value combo the api needs to pass to get dispatched to the right target action inside your application:
...
definitions:
MyUniqueCommandARequest:
type: object
properties:
rest_call:
type: string
enum:
- myUniqueCommandA
default: myUniqueCommandA
...
MyUniqueCommandBRequest:
type: object
properties:
rest_call:
type: string
enum:
- myUniqueCommandB
default: myUniqueCommandB
...
In the above example, the property "rest_call" is what my underlying system uses to dispatch the request to the right underlying operation.
The request object for myUniqueCommandA has its rest_call attribute defined as enum["myUniqueCommandA"]. The request object for myUniqueCommandB has its rest_call attribute defined as enum["myUniqueCommandB"].
Since these are defined as a single value enums that are also defaulted to that same value, the generated swagger classes that calls these apis will be wired to pass their correct routing value automatically.
I just faced the issue while using Spring Security REST API plugin for grails.
When I want to update some object of certain class. I then call the URL with PUT in it and the object which needed to updated.
But suppose I send the different object of different class, It still takes the id from there gets the object of required class and updates it.
Example: I want to update the test object, so I call /com/test with PUT and object of com.Test domain (this works great)
But if I call the same URL /com/test with object of com.Test123 domain, it then takes the id and gets the object of Test domain with the same id and updates it.
I don't need this. If the class doesn't match, it must show the class mismatch error.
Is it some configuration issue?
What is the wire format for your PUT request.
If it is JSON then the server will simply try and re-create your server side object from the JSON data. And so long as the signatures match the object will be unmarshalling without an error.
To get the sort of behavior you are looking for you need to use XML and JAXB. In this case the XML sent across will have enough info to ensure the correct class is created when unmarshalling.
I have basic knowledge of Java's reflection API - therefore, this is not only a question of how, it's a question of whether it's possible and whether I'm going about a solution the best way.
We're doing some acceptance testing of multiple, interrelated projects; each of these projects retrieve data from a MongoDB store using an in-house abstraction API. To facilitate this testing, each component needs some pre-loaded data to be available in the database.
I'm building a command-line tool to accept a DTO (pre-compiled class binary), for loading of multiple instances using the morphia ORM library. I would like each member of our team to be able to run the generator passing in via cli their DTO (in jar or directory form), and a file (csv or otherwise) for instantiating a desired amount of records.
I have the class loading working fine with URLClassLoader. Now I'm trying to instantiate an instance of this class using data from a file.
Is this possible? Would serialized objects be a better approach?
That's perfectly possible using the Java Reflection API :
Load Class instance by name (Class.forName(className), you don't really need the ClassLoader instance)
Grab Constructor instance of constructors have parameters and invoke newInstance(Object... args) on this constructor instance to create an instance of your DTO class.
Invoke getDeclaredFields() on your Class instance and iterate over them to set their values (field.set(instance, value)). Make sure to invoke field.setAccessible(true) to be able to access private fields.
If by "serialized objects" you mean canned instances, then no, by loading properties from a text file you allow much easier tweaking of test data (if that's a goal), including the number of objects.
But sure, it's possible; unmarshal the data from the input file and use it to initialize or construct the object in question like you would in regular code.