Passing parameters in Client server model - web-services

I have a Client that communicate with the Server using web-services.
The Model layer is implemented in the server side,
and I wonder what is the right way to pass parameters in the web-service methods.
Should it pass primitive types (and DataSets) or Objects?
For example, If I have the object Pesron, and I want my web-service to add new person
Should I pass the Object to the web-service method (i.e. AddNewMethod(Person newPerson)) or,
should I pass Primitives to the web-service method (i.e. AddNewMethod(int pId, String pName))
Thanks.

you should use AddNewMethod(Person newPerson)).
Reasons:
1. Cleaner code.
2. Less prone to errors.
3. You can use data model client side.
4. You are not going for overloading of functions? AddNewMethod(int pId, String pName) gives you options for overloading.

Related

while writing a Chaincode (Hyperledger-fabric) in Golang I am confused while fallowing documentation

I am confused ,when I am following fabric-samples (asset-transfer-basic --->https://github.com/hyperledger/fabric-samples/blob/main/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go) for writing smart contract in Golang , the methods takes ctx contractapi.transcationcontextinterface as there function parameter , but when I am trying to refer other chaincode's on internet every one else are taking stub shim.chaincodesubinterface as there function parameter , if I use stub as my function parameter then how can I make use of clientidenty methods (cid package) , and in asset-transfer-basic code Init/Invoke are not mentioned also in main function when creating a new chaincode ( assetChaincode, err := contractapi.NewChaincode(&SmartContract{}) ) SmartContract{} does not implement contractinterface . I am try to do a project on ERC20 token for applying for jobs so please help
The examples you have found that include an Init and Invoke function, and take ChaincodeStubInterface as a parameter are using the older and lower-level fabric-chaincode-go API directly. The asset-transfer-basic sample is using the newer and higher-level fabric-contract-api-go API. This is built on top of the lower-level API and allows you access to all the same information as the lower-level API (note that the transaction context passed into transaction functions using the higher-level API has a GetStub method to obtain the corresponding low-level ChaincodeStubInterface).
I would recommend using the Contract API as demonstrated by the asset-transfer samples. The two approaches are functionally equivalent but the Contract API provides a cleaner abstraction requiring less boiler-plate code.

how to pass object of a class created inside client to server?

I have a client and a server class in which i am sending message from client to server by making use of TCP sockets.
I have a class created in client.cpp named as Employee consisting of variables such as :
int emp_id;
char *emp_name;
float emp_weight;
My question is as follows:
1) How to send object of the employee class from client side to the server i.e how will i pass employee_object shown as follows to server:
employee_object.emp_id=10;
employee_object *emp_name=new char[30];
employee_object.emp_weight=50.2;
Any help will be of great help.I am doing this to make my self clear how to pass different objects of classes from client to server.
You have two main options: directly write the struct or class to the socket, or "serialize" it.
If you do a direct write, it's quite simple, but it requires you take care that your client and server have the same "width" (32 or 64 bit) and "endianness" (little or big). If you're dealing with regular Intel or AMD desktop or server machines only, this isn't much of an issue.
If you want to "serialize," the sky is the limit. Look up Protocol Buffers, Cap'n'Proto, JSON, etc. There are tons of libraries for this, but Stack Overflow is not the site to figure out which one you should use--you'll have to do some research. Some key considerations are whether the format is human-readable (like JSON) and whether it is fast (like Cap'n'Proto, or the direct method mentioned previously).

SFDC Apex Code: Access class level static variable from "Future" method

I need to do a callout to webservice from my ApexController class. To do this, I have an asycn method with attribute #future (callout=true). The webservice call needs to refeence an object that gets populated in save call from VF page.
Since, static (future) calls does not all objects to be passed in as method argument, I was planning to add the data in a static Map and access that in my static method to do a webservice call out. However, the static Map object is getting re-initalized and is null in the static method.
I will really appreciate if anyone can give me some pointeres on how to address this issue.
Thanks!
Here is the code snipped:
private static Map<String, WidgetModels.LeadInformation> leadsMap;
....
......
public PageReference save() {
if(leadsMap == null){
leadsMap = new Map<String, WidgetModels.LeadInformation>();
}
leadsMap.put(guid,widgetLead);
}
//make async call to Widegt Webservice
saveWidgetCallInformation(guid)
//async call to widge webserivce
#future (callout=true)
public static void saveWidgetCallInformation(String guid) {
WidgetModels.LeadInformation cachedLeadInfo =
(WidgetModels.LeadInformation)leadsMap.get(guid);
.....
//call websevice
}
#future is totally separate execution context. It won't have access to any history of how it was called (meaning all static variables are reset, you start with fresh governor limits etc. Like a new action initiated by the user).
The only thing it will "know" is the method parameters that were passed to it. And you can't pass whole objects, you need to pass primitives (Integer, String, DateTime etc) or collections of primitives (List, Set, Map).
If you can access all the info you need from the database - just pass a List<Id> for example and query it.
If you can't - you can cheat by serializing your objects and passing them as List<String>. Check the documentation around JSON class or these 2 handy posts:
https://developer.salesforce.com/blogs/developer-relations/2013/06/passing-objects-to-future-annotated-methods.html
https://gist.github.com/kevinohara80/1790817
Side note - can you rethink your flow? If the starting point is Visualforce you can skip the #future step. Do the callout first and then the DML (if needed). That way the usual "you have uncommitted work pending" error won't be triggered. This thing is there not only to annoy developers ;) It's there to make you rethink your design. You're asking the application to have open transaction & lock on the table(s) for up to 2 minutes. And you're giving yourself extra work - will you rollback your changes correctly when the insert went OK but callout failed?
By reversing the order of operations (callout first, then the DML) you're making it simpler - there was no save attempt to DB so there's nothing to roll back if the save fails.

Having problems getting a List of Objects back from Restful service

Hey guys. I've developed some services in REST that are running on Glassfish 3.1.
I have a Java SE application and I am using Jersey as the client api.
public <T> T findAll_JSON(Class<T> responseType) throws UniformInterfaceException {
WebResource resource = webResource;
return resource.accept(MediaType.APPLICATION_JSON).get(responseType);
}
This is the client code that is generated by Netbeans.
My main problem is passing a list of objects as the response type
Here is the client code.
List<PkgLine> pkgLine = service.findAll_JSON(List.class);
System.out.println(pkgLine.get(5).getLineStatus());
service.close();
Obviously this is not working because the response needs to be a List of PkgLine. How do I pass that as a generic? My service is set to return the List of PkgLine. Thanks.
The problem is "erasure". You can declare a List<PkgLine> in your program, but at runtime the information that the objects in the List are PkgLines is erased. List<String>, List<PkgLine> and List<Object> are all the same type at runtime. (There's a reason why this is so; I won't explain it here but you can look up "erasure" if you are interested.)
The objects in the List are still PkgLines of course, but to the List they are just Objects, and you'll have to cast each one to a PkgLine. It's not pretty.
List<?> pkgLine = service.findAll_JSON(List.class);
System.out.println(((PkgLine)(pkgLine.get(5))).getLineStatus());
service.close();
What about parsing an array? It has the same json represantation.
You could write something like this:
resource.accept(MediaType.APPLICATION_JSON).get(PkgLine[].class);

SOAP Webservice error - design practice

I need to design a SOAP api (my first one!). What are the best practices regarding errors returned to the caller.
Assuming an api as follow
[WebMethod]
public List<someClass> GetList(String param1)
{
}
Should I
Throw an exception. Let the SOAP infrastructure generate a SOAP fault -- and the caller would have to try/catch. This is not very explanatory to the caller
Have the return parameter be a XMLDOcument of some sort, with the first element being a return value and then the List.
Looking at the return SOAP packet I see that the response generated looks like the following
<GetListResponse>
<GetListResult>
...
...
</GetListResult>
</GetListResponse>
Can we somehow change the return packet so that the "GetListResult" element is changed to "GetListError" in case of error
Any other way?
Thanks!
Probably the most appropriate SOA pattern to follow would be a Fault Contract, which is essentially a Data Contract that is wrapped in the SOAPException.
I am posting examples in .NET, since it looks like that is what you are using (and that is what I know :) )
In WCF, you can define a DataContract, then decorate your OperationContract interface with a a "FaultContract" attribute that specifies it as the return value:
public partial interface MyServiceContract
{
[System.ServiceModel.FaultContract(typeof(MyService.FaultContracts.ErrorMessageFaultContract))]
[System.ServiceModel.OperationContract(...)]
ResponseMessage SOAMethod(RequestMessage request) {...}
}
For ASMX web services, (as it appears you are using from your code snippet), you can't use this attribute or setup. So to implement the pattern, you would need to:
Define a serializable class to hold your exception information (i.e. ErrorData)
When an exception is thrown in your service, catch it and in your error handling code, add the info to the ErrorData class
Append the serialized ErrorData class to a SoapException class:
SoapException mySoapException = new SoapException(message, SoapException.ServerFaultCode, "", serialzedErrorDataClass);
Throw the SoapException in your code
On your client side, you will need to deserialize the message to interpret it.
Kind of seems like a lot of work, but this way you have total control of what data gets returned. Incidentally, this is the pattern that is used by the ServiceFactory from Microsoft patterns & practices for ASMX web services.
There is some good information on Coding Horror.
You can cause the correct fault to be returned from old ASMX services, but it's not easy. First of all, you'll have to hand-code the WSDL, because the ASMX infrastructure will never create Fault elements in a WSDL. Then, you have to serialize the desired fault data into an XmlElement that you will then provide as the Detail property of the SoapException that you will throw.
It's much easier with WCF. You can declare a number of FaultContracts for each operation, and WCF will generate the correct WSDL to refer to them. You then simply throw a FaultException, where type T is the type of the FaultContract. Pass the T instance to the constructor, and you're all set.
I can't give you specifies for .net (which seems to be what you're asking), but SOAP provides a mechanism for expressing strongly-typed exceptions. The SOAP fault element can have an optional FaultDetail sub-element, and this can contain arbitrary XML documents, such as your GetListError. These document types should be defined in the WSDL as a wsdl:fault inside the wsdl:operation
The trick is persuading the web service stack to turn an exception (which is the "correct" way of writing your business logic) into a properly marshalled fault detail. And I can't help you with that bit.