How to specify custom streaming parser in eclipse microprofile restclient? - jax-rs

I need to consume a large payload ( hundreds of MB's) and am using eclipse microprofile restclient to make REST call, but I am not aware how I can specify my own JSON parser to be used for this particular call. Appreciate any examples/references.

Related

How to display a json response mapped pojo in sightly

I have a sling servlet that invokes a 3rd party api and fetches a json response. I have mapped the json response to a pojo class using Jackson. I now have to display this dynamically fetched and mapped response in sightly. How do i do that? I am stuck after the response mapping
With the new version of Sling Models, you can directly expose a model as a Servlet by specifying a resource type and the selector to use in your model annotations. When the Model is loaded into Apache Sling, it automatically registers a Servlet corresponding to the model, allowing you to with nearly zero additional code, create a Servlet to access a JSON representation of the model. That’s super cool!
The above life makes your Life Easier!!
You can have all your objects in Sling Model. Since the sling model acts as a servlet You can make the AJAX call and get a real-time response.
Please refer to this document.
https://blogs.perficient.com/2018/07/26/no-servlets-required-exporting-data-with-sling-models/
The correct path is:
HTL/Sightly -> Sling Model -> OSGi Service -> External API
So you have to extract the code that fetches the data into an OSGi service.
But please secure your code that calls the external API. As example if the External API is not responding or is extremely slow, it could consume all available threads of AEM. Then AEM could be completely unusable. To secure it, you could use as Example a Semaphore.
Assuming the JSON returned is arbitrary, the best thing to do is simply display it as a string. To do that, instead of mapping the JSON response to a POJO I would recommend adapting a Sling model to the response.
Then, you can set that Sling model to be the model in your sightly code, using data-sly-use.model, and in the Sling model constructor you can set the response value to an attribute of the sling model.
Then all you'd need to do is put that attribute in a ${} in the sightly html.
If the format/structure of the JSON isn't completely unknown, you could use the POJO in the sightly. Create some conditionals to test what attributes the POJO has, so you can put them into the sightly code.

what is the easy way to manually parse the RAML file in mule?

In mule application I am trying to parse RAML file. I knew that APIKit is doing same as it creates flows after parsing the RAML file. But still, what if I want to parse it in middle of the flow manually?
I have seen the raml parsers available but not finding the proper usage of those javascript libraries or java libraries on how to use them in mule application..
Yes you can parse your RAML in your java application using java class or groovy component implementing java.
There are java parser available like RamlModelBuilder which you can use to parse your application RAML like validation of your RAML file, getting APIs name, getting all resources name, method name, scopes, security schema and their names, query parameters, headers and many more...
Just check the example how it is used here. You can simply create a java class and get your RAML parsed
https://github.com/anirban37/Anirban-Custom-Oauth-Policy/blob/master/Anirban-RAML-Oauth-V3/OauthPolicies.xml#L594.
ramlModelResult = new RamlModelBuilder().buildApi(ac.getRaml())
will give you the current RAML file access of the application in the java class
Theres nothing in Mule to work with the RAML file at runtime.
But you can create any Java component that uses RAML Java libraries and invoke that from Mule in your flows.
The Mule4 SDK is one way of extending mule through Java.
For more information on Mule SDK can be found here https://mule4-docs.mulesoft.com/mule-sdk/v/1.1/
You can also invoke Java classes but they need to be decoupled from the Mule API and you need to extract any variables, properties or payload and explicitly pass the values to your class. For example passing a static String and a flow var as arguments to a Java constructor:
<java:new class="com.foo.AppleEater" constructor="MyClass(String, Apple)">
<java:args>#[{name: 'some string arg', apple: vars.apple}]</java:args>
</java:new>
In your class you could use the RAML Java libraries, and pass the file or path to RAML file to load from the classpath.
More on Java integration with Mule 4 here: https://docs.mulesoft.com/mule-runtime/4.1/intro-java-integration

Spring Auto REST Docs + Spring Data REST? HATEOAS?

I really like the idea of using Javadoc comments for auto-generating REST Docs!
Huge parts of our REST API are automatically generated by Spring Data REST (by adding #RepositoryRestResource to Repositories). It would be great if REST Docs could also be generated for these - that would be a very high degree of automatition.
But unfortunately most "auto-"snippets are "empty" (e.g. auto-response-fields.adoc only contains a list of links[]-Attributes). I guess the reason could be that the REST Controllers are probably created dynamically by Spring Data REST. Currently I do not see how to re-use the Javadoc comments for them.
Is there any way to auto-generate REST Docs for such REST APIs that are provided by Spring Data REST?
It would even be helpful to manually tell Spring Auto REST Docs which classes are used in requests and responses instead of letting it discover it statically - is that possible?
And we also add HATEOAS "_links" to most response Resources (by providing ResourceProcessors as Beans). These links contain "title"s which are used by Spring REST Docs - if we list all of them with HypermediaDocumentation.linkWithRel(...). This is a bit redundant, and it would be nice if all the _links with "title"s could be processed automatically. (But this can be done by listing all of them in some extra code, so it is not as bad as with Spring Data REST.)
If necessary, I could also create an example project for what I am talking about.
Answer to the question whether one can manually tell Spring Auto REST Docs which classes to use for the documentation:
Spring Auto REST Docs allows to specify the request and response classes to use for the documentation. This can be done with requestBodyAsType and responseBodyAsType. In a test it looks like this:
.andDo(document("folderName",
requestFields().requestBodyAsType(Command.class),
responseFields().responseBodyAsType(CommandResult.class)));
This is from a test in the example project.

Changing the JSON format for spring-data-rest

Currently spring-data-rest is returning JSON in HAL format in a spring-boot project of mine. I am using an ember.js frontend and want to use jsonapi (http://jsonapi.org/) specification.
How might I register a new JSON formatting strategy given I will need to write the formatter myself as one does not exists yet?
This is how you can customize the HATEOAS that Spring Data REST produces:
https://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.customizing-json-output
If you need to completely replace the JSON representation with your own, then you can write and register your own org.springframework.core.convert.converter
Or you write your custom REST endpoints in a plain old #RepositoryRestController and implement your own REST endpoints. (<= I suggest try this)

Canonical data model

I am building an application that exposes a Rest API and on the backend communicates and orchestrates multiple SOAP services to build the responses to the REST API. I have been reading about Canonical Data Models and how they can help me loosely couple these backend SOAP services.
Should I be using a canonical Data Model between my Rest API and the backend services?
At the moment the backend SOAP responses are unmarshalled to Java objects using JAXB. I then use scripts to map the jaxb objects to the a map that represents the structure I want to return as JSON and simply convert the Map to Json via my Rest API.
So SOAP -> jaxb Java Object -> Java Map(representing JSON) -> Json
Should I add another step in here for a Canonical Model?
So SOAP -> jaxb Java Object -> CANONICAL MODEL not representing SOAP or JSON structure -> Java Map(representing JSON) -> Json
Is this a good fit for a CDM? Or does adding this extra level redundant?
I think you're talking about having a facade between you and the services rather than a CDM.
You would map the jaxb generated objects into internal objects, perform application logic on these, and then map these to the objects representing your JSON interface.
The jaxb-internal mapping will decouple your application from the interfaces you are consuming.
The internal-to-json mapping will decouple the interface you expose to your consumers from your internal objects.
Whether this is worth it or not depends on the complexity of your environment, what the cost & likelihood of change is. For instance it might be acceptable to be tightly coupled to services which share and expose a mature and versioned canonical model. It's a very different risk profile if you are consuming a set of ad-hoc or third party interfaces.
As far as I know canonical data model means a common data model that represents all possible message formats and/or protocols. For an example, in Mule MuelMessage is a canonical data model because every message we sent, Mule creates the MuleMessage which represents your message irrespective of the protocol we use. So creating such a canonical data model is a bit difficult, in general
Coming to your case, I don't know how complex your SOAP objects are. If they are too complex, i.e., having multi-levels, then it would be a difficult job. My suggestion is, instead of having a canonical data model, why can't your write your own custom transformer (see if you can use a built in transformer) which parses and transforms your SOAP message to the corresponding JSON response. You can have a common transformer interface but with multiple implementations do perform parsing and transforming, depends on your SOAP message.
Hope this helped.