Can someone tell me or give a ready-made CRUD example using WebFlux, RScoket and Spring (or SpringBoot)?
I studied the RSocket documentation, WebFlux, also wrote my simple examples, but I would like to see a real CRUD application using basic methods using RSocket.
I'll be very grateful.
Thanks.
I have maintained a Spring/RSocket sample project with 4 basic interaction modes of RSocket.
If you only require request/reply case for simple CRUD operations, check the request and response mode, and select a transport protocol, TCP or WebSocket.
To implement CRUD operations, just define 4 different routes for them, like define the RESTful APIs using URI, you have to have a good plan for the naming, but in RSocket there are no HTTP methods to help you to differentiate the same routes.
For example, in the server side, we can declare a #Controller to handling messages like this.
#Controller
class ProfileController {
#MessageMapping("fetch.profile.{name}")
public Mono<Profile> greet(#DestinationVariable String name) {
}
#MessageMapping("create.profile")
public Mono<Message> greet(#Payload CreateProfileRequest p) {
}
#MessageMapping("update.profile.{name}")
public Mono<Message> greet(#DestinationVariable String name, #Payload UpdateProfileRequest p) {
}
#MessageMapping("delete.profile.{name}")
public Mono<Message> greet(#DestinationVariable String name) {
}
}
In the client side, if it is a Spring Boot application, you can use RSocket RSocketRequester to interact with the server side like this.
//fetch a profile by name
requester.route("fetch.profile.hantsy").retrieveMono()
//create a new profile
requester.data(new CreateProfileRequest(...)).route("create.profile").retrieveMono()
//update the existing profile
requester.data(new UpdateProfileRequest(...)).route("update.profile.hantsy").retrieveMono()
//delete a profile
requester.route("delete.profile.hantsy").retrieveMono()
Of course, if you just build a service exposed by rsocket protocol, the client can be a rsocket-js project or other languages and frameworks, such as Angular, React or Android etc.
Update: I've added a crud sample in my rsocket sample codes, and I have published a post on Medium.
Related
I have created a demo microservices application implemented with the help of Azure Function Apps. For separation of concerns, I have created an API Layer, Business Layer, and a Data Layer.
The API layer, being the function app, calls the business layer which implements the business logic while the data layer implements logic for storing and retrieving data.
After considerable thought, I have decided to use query-based API versioning for my demo.
The question I have is,
What is the best way to organize my code to facilitate this? Is there any other way to organize my code to accommodate the different versions apart from using different namespaces / repos?
As of now, I've created separate namespaces for each version but this has created a lot of code duplication. Also after getting it reviewed by some of my friends, they raised the concern that If separate namespaces are being used I would be forcing legacy systems to change references to the new namespace if they need to update which is not recommended.
Any help would be appreciated.
The simplest way to implement versioning in Azure Functions is using endpoints. The HttpTrigger Attribute allows the definition of a custom route where you can set the expected version.
// Version 1 of get users
[FunctionName(nameof(V1UserList))]
public static IEnumerable<UserModel> V1UserList(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "v1/users")]HttpRequest req, ILogger log)
{
}
// Version 2 of get users
[FunctionName(nameof(V2UserList))]
public static IEnumerable<UserModel> V2UserList(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "v2/users")]HttpRequest req, ILogger log)
{
}
When deploying each version in isolation a router component is required to redirect requests to the correct API endpoint.
The router component can be implemented in Azure using different services, such as:
Azure Function Proxies : you can specify endpoints on your function app that are implemented by another resource. You can use these proxies to break a large API into multiple function apps (as in a microservice architecture), while still presenting a single API surface for clients.
API Management :Azure API Management supports importing Azure Function Apps as new APIs or appending them to existing APIs. The process automatically generates a host key in the Azure Function App, which is then assigned to a named value in Azure API Management.
Sample code for Versioning APIs in Azure Functions
I am new to RESTful API client development. I have a got the sample client code to integrate to REST Server. Below is the the snap shoot of same.
public TsbPublishClient() {
client = javax.ws.rs.client.ClientBuilder.newClient();
webTarget = client.target(BASE_URI).path("publication");
}
public <T> T getJson(Class<T> responseType, String product, String version, String category) throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path(java.text.MessageFormat.format("registry/{0}/{1}/{2}", new Object[]{product, version, category}));
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType);
}
public void close() {
client.close();
}
My question is how do i invoke the getJson() method from my main class. The return type is T and it accepts responseType parameter which is of type Class <T>
Thanks in Advance.
I'm a bit surprised that you want to use JAX-WS to access a RESTful API. In this technology, a web service operation invocation is represented by an XML-based protocol such as SOAP.
There are several technologies to do a call to a RESTful applications. Here are two of them:
Restlet - a lightweight and robust Java REST framework that tackles both client and server sides.
JAX-RS (JSR 311: JAX-RS: The Java API for RESTful Web Services) - a standardized API to both consume and produce RESTful applications. Restlet provides an implementation of this specification.
Following code describes a sample of client with Restlet:
ClientResource cr = new ClientResource("http://(...)/contacts");
MyDataBean bean = cr.get(MediaType.APPLICATION_JSON);
Following code describes a sample of client with JAX-RS:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://(...)")
.path("contacts");
MyDataBean bean = target
.request(MediaType.APPLICATION_JSON_TYPE)
.get(MyDataBean.class);
Both tools can leverage content (JSON, XML, YAML, ...) / POJO conversion with for example Jackson.
Hope it helps you,
Thierry
I have developed a web application based on Restlet API. As I am adding more features over time, I need sometimes to reuse similar group of REST API under different endpoints, which provides slightly different context of execution (like switching different instances of databases with same schema). I like to refactor my code to make the API reusable and reuse them at different endpoints. My initial thinking was to design an Application for each reusable API and attach them on the router:
router.attach("/context1",APIApplication.class)
router.attach("/foo/context2",APIApplication.class)
The API should be agnostic of configuration of the REST API. What is the best way to pass context information (for example the instance of database) to the Application API? Is this approach viable and correct? What are the best practices to reuse REST API in Restlet? Some code samples would be appreciated to illustrate your answer.
Thanks for your help.
I have see this basic set-up running using a Component as the top level object, attaching the sub applications to the VirtualHost rather than a router, as per this skeleton sample.
public class Component extends org.restlet.Component
{
public Component() throws Exception
{
super();
// Client protocols
getClients().add(Protocol.HTTP);
// Database connection
final DataSource dataSource = InitialContext.doLookup("java:ds");
final Configuration configuration = new Configuration(dataSource);
final VirtualHost host = getDefaultHost();
// Portal modules
host.attach("/path1", new FirstApplication());
host.attach("/path2", new SecondApplication(configuration));
host.attach("/path3", new ThirdApplication());
host.attachDefault(new DefaultApplication(configuration));
}
}
We used a custom Configuration object basically a pojo to pass any common config information where required, and used this to construct the Applications, we used separate 'default' Contexts for each Application.
This was coded originally against restlet 1.1.x and has been upgraded to 2.1.x via 2.0.x, and although it works and is reasonably neat there may possibly be an even better way to do it in either versions 2.1.x or 2.2.x.
I've built my first grails application. My URL mappings are what the default application provides:
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
Senario
I have a controller called ColorController with actions save and list. It simply does something like this:
def save () {
def colorInstance = new Color(params)
colorInstance.save(flush: true)
}
def list () {
[colorList: Color.list, colorTotal: Color.count()]
}
I would like to build a simple API for these actions.
The save action should accept parameters as JSON and provide a successful message if the records save.
The list action should provide the list as JSON
Questions
Should I make a separate URL mapping for api? (e.g. http://<domain>/<app>/rest/controller/action)
Should I be making a separate controller for my API's
I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that?
If I use the same controller, how can I modify these simple actions to do what I need.
Before even looking below for my opinion/answers I would suggest to visit this SO Question for the basic understanding of RESTful WS in Grails.
Opinions:
"The save action should accept parameters as JSON and provide a successful message if the records save" - Save is mapped to POST RESTful. Instead of binding a JSON body to params it is bound to the request. In order to access the JSON object you just need to use request.JSON in the action method.
request.JSON instanceof JSONObject
"The list action should provide the list as JSON" - list() action is mapped to a GET Request and you can render the map as JSON in the list() as below
//Controller list()
import grails.converter.JSON
def list () {
[colorList: Color.list, colorTotal: Color.count()] as JSON
}
Answers to Questions:-
Should I make a separate URL mapping for api?
Abiding by the basics of REST, the client should only access the resource (Color in this case) and should not bother about the underlying controller or action. The server side logic should be abstracted from the client. URL Mapping is what the client would use to as form of request. I would have something like this in my url mapping for Color Resource.
/color/$id?(resource: "color")
or
/color/$id?(controller: 'color'){
action = [GET: "list", POST: "save"]
}
Should I be making a separate controller for my API's? - Depends on the way the App is designed. You also can have the above controller as the API. For example, currently I am working on a grails app which used AngularJS in the front End which connects to the Grails APP RESTFully. In order to achieve I had a RestClientController which works as an API to Angular. The rationale behind having a REST api in the same app is that in future we can expose the underlying service to external clients other than the Angular client present in the app itself.
I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that? - You can use Spring Security here as well. In my case I am using the plugin and I secure the controller by using the plugin's annotated component #Secured. I have custom OAuth enabled as well for authorization which interacts to the company wide LDAP and AD Groups.
If I use the same controller, how can I modify these simple actions to do what I need. - I think you would have got the answer to this question by now (after going through the SO question I mentioned above). Here is my opinion, controller actions can route to appropriate service classes which does the business implementations based on the request parameters.
For example,
//Action
def show(){
if(params.id){
colorService.getColor()
} else {
colorService.searchColor()
}
}
In the above example, the url mapping would be /color/123 or /color. In the former case, it will get the color and in the later it will search the colors
TL;DR:
What is a good and testable way to implement the dependency between the ViewModels and the WCF services in a MVVM client?
Please read the rest of the question for more details about the problems I encountered while trying to do this:
I am working on a silverlight client that connects to a wcf service, and I want to write unit tests for the client.
So I'm looking for a good solution for using the wcf clients in my ViewModels and testing that interaction. I have found two solutions until now:
Solution 1: This is actually how I have implemented it until now:
public class ViewModelExample
{
public ViewModelExample(IServiceClient client)
{
client.DoWorkCompleted += ..
client.DoWorkAsync();
}
}
//This is how the interface looks like
public interface IServiceClient
{
event EventHandler<AsyncCompletedEventArgs> DoWorkCompleted;
void DoWorkAsync();
}
//I was able to put the interface on the generated clients because they are partial classes, like this:
public partial class GeneratedServiceClient : IServiceClient
{
}
The good part: it's relatively easy to mock
The bad part: my service client lives as long as my ViewModel, and when I have concurrent requests I don't know which answer belongs to which request.
Solution 2: Inspired by this answer
WCF Service Client Lifetime.
public class ViewModelExample
{
public ViewModelExample(IServiceFactory factory)
{
var client = factory.CreateClient();
client.DoWorkCompleted += ...
client.DoWorkAsync();
}
}
The good part: each request is on a different client, so no more problems with matching requests with answers.
The bad part: it's more difficult to test. I would have to write mocks for both the factory and the wcf client every time. This is not something I would like to do, since I alreay have 200 tests... :(
So my question is, how do you guys do it? How do your ViewModels talk to the wcf services, where do you inject the dependency, and how do you test that interaction?
I feel that I'm missing something..
Try having a Func<IServiceClient> injected into your VM instead of the a client instance; you'll have a 'language-level factory' injected instead of building a class for this. In the factory method you can instantiate your client however you want (each access could create a new instance for that for example).
The downside is that you'll still have to touch your tests for the most part, but I assume it will be less work:
public ViewModelExample(Func<IServiceClient> factoryMethod)
{
var client = factoryMethod();
client.DoWorkCompleted += ...
client.DoWorkAsync();
}
The WCF service should have it's own tests that confirm the functionality of itself.
You should then be mocking this WCF service and writing unit tests within your consumers.
Unfortunately, it's a pain and something we all have to do. Be pragmatic and get it done, it will save you getting bitten in the future.
Are you using IoC container by a chance? If you had, this problem would be totally mitigated by container (you'll simply register IService dependency to be created as brand new upon each request).
If that's not the case, then
I would have to write mocks for both the factory and the wcf client every time
is how you deal with this kind of "problems". The cost is relatively small, probably 2-3 extra lines of code per test (all you have to do is setup factory mock to return service mock, which you do need either way).