I want to implement a webservice client in iOS which uses SOAP and XML for requests/responses.
My view starts the initial businnes logic (a user presses a button or something and initiates some businnes method called method_A).
So I have a class with method_A and this method checks if the user is logged in etc and then starts the request asynchronous via the SOAPConnector-class. So the UI is not blocked (asynchronous).
The SOAPConnector-class takes the XML and handles the requests. I use therefore NSURLRequest and NSURLConnection with sendSynchronousRequest.
The response is sended back to a Response-class which takes the response. This class then wants to parse the response XML. Therefore I use an extra class called XMLManager which uses NSXMLParser to parse the xml. But again here we need a delegate which gets the parsed xml. And again after parsing I have to implement an extra method to give back the parsed xml to the first class which initiated the request.
I am really wondering if this is the right way. The first problem is asnychronous request to not block the UI (the first callback). The second problem is the parsing where I am forced to use the delegate (the second callback). This results in a lot of classes and methods and I doubt this is the right way. The classes' only purpose is to manage the delegate and async problems. So I am asking for any suggestions and help how to solve this. Do you know some good design patterns to solve this problem?
Apart from some inconsistencies in the way you describe the design patterns you've selected:
and then starts the request asynchronous
vs.
I use therefore NSURLRequest and NSURLConnection with
sendSynchronousRequest.
That said, your approach seems sound. Addressing the issues you've identified:
I use therefore NSURLRequest and NSURLConnection with
sendSynchronousRequest.
Isn't that the purpose of using an asynchronous API? If your NSURLConnection is really operating asynchronously, that issue should be covered.
The second problem is the parsing where I am forced to use the
delegate
This approach does result in more classes, delegation, etc. but it conforms to best practices when it comes to testing. If you are performing unit testing or other testing strategies (you are aren't you?) then testing in isolation is all the harder unless you breakdown this process functionally.
If you have access to the book Test-Drive iOS Development there is a great section on the best practices for consuming web services with a view toward testability.
Related
I am writing a service where the client makes an API call to my service, and my service then augments the request payload, then passes it on to another service. For my API, what should the HTTP method be if it's not interacting with a database?
what should the HTTP method be
Key idea: the fact that your server communicates with another API, rather than a database, or a filesystem, is an implementation detail; details of your implementation are not supposed to be leaking into your messages.
Given that the incoming request has a message body; GET, HEAD, DELETE are all right out, because those methods have no defined semantics for a payload.
POST/PUT/PATCH are all possible.
Ideally, you would match the method token that you are using to talk to your back end. This is essentially how a reverse proxy works. You're just playing man in the middle, after all, so it shouldn't be too much of a surprise that the request semantics match.
They don't always, of course - and you might want to inject your own semantics if you find that the API you are calling has made poor method choices in its own design.
When in doubt, it is okay to use POST
One of the REST principles — namely, ‘Layered System’ constraint — implies that:
each component cannot "see" beyond the immediate layer with which they are interacting
So you actually should not make any difference between ‘simple’ and ‘proxied’ API calls.
I am using Restlet 2.2.1 and building Rest services. As you know, Router is used to attach either Restlet or Resource as target.
Router router = new Router( getContext() );
router.attach("/healthcheck1",HealthCheckResource.class );
router.attach("/healthcheck2", new HealthCheckRestlet() );
Then you can implement your logic in handle()
Wondering which is best one to use? I know Resource has a very definite life cycle (doInit, handle, release ...) and good place to implement one time logic like initialization.
Attach a ServerResource subclass rather than a Restlet instance when feasible, for a couple of reasons:
Resources are the natural way to structure RESTful APIs. When you use the #Get, #Put, etc. annotations on a resource class, you're effectively documenting that part of your RESTful API, and there are tools that can extract that information to create online documentation automatically. If you use a Restlet instance, its behavior in response to GET, PUT, etc. is not immediately apparent. Ironically, using a Restlet makes it easier to write APIs that are not RESTful.
A separate instance of the resource class is created for each request, meaning that an instance is normally confined to a single thread, which simplifies reasoning about thread-safety. In constrast, the same Restlet instance will be used for all handle(...) calls, potentially leading to complicated thread-safety requirements.
Because each request gets its own resource instance, the resource methods might need to appeal to internal services that are passed via the application context or injected into the resource (see this Restlet extension).
Incidentally, your comment about "one time logic like initialization" might be a misunderstanding. The doInit method is called for each instantiated resource (i.e., once per request for that resource), not one time only.
Note that I'm recommending against directly subclassing Restlet as an end target for a resource URL, except maybe for trivial resources. Using subclasses of Restlet is a different matter: Attaching a Filter which wraps a resource is fine.
I have just completed my first API in Apigility. Right now it is basically a gateway to a database, storing and retrieving multi-page documents uploaded through an app.
Now I want to run some processing on the documents, e.g. process them through a 3rd party API or modify the image quality etc., and return them to the app users.
Where (in which class) do I generally put such logic? My first reflex would be to implement such logic in the Resource-Classes. However I feel that they will become quite messy, obstructing a clear view on the API's interface in the code and creating a dependency on a foreign API. Also, I feel limited because each method corresponds to an API call.
What if there is a certain processing/computing time? Meaning I cannot direct respond the result through a GET request. I thought about running an asynchronous process and send a push notification to the app, once the processing is complete. But again, where in the could would I ideally implement such processing logic?
I would be very happy to receive some architectural advice from someone who is more seasoned in developing APIs. Thank you.
You are able to use the zf-rest resource events to connect listeners with your additional custom logic without polluting your resources.
These events are fired in the RestController class (for example a post.create event here on line 382).
When you use Apigility-Doctrine module you can also use the events triggered in the DoctrineResource class (for example the DoctrineResourceEvent::EVENT_CREATE_POST event here on line 361) to connect your listeners.
You can use a queueing service like ZendQueue or something (a third party module) built on top of ZendQueue for managing that. You can find different ZF2 queueing systems/modules using Google.
By injecting the queueing service into your listener you can simply push your jobs directly into your queue.
I'm developing an app using MonoTouch and have to get some data from a 3rd party web service. I have a WCF binding to do such.
The particular web service method I am calling could potentially return an XML string in the range of several hundred megabytes, which could take a while to download to a mobile device.
I'm looking for some way to capture how many bytes have been read from the network at the system level, with the end-game being to display a progress indicator to the user. Is there some way I can achieve this using Behaviors?
Note, I don't have any way to modify the web service code to return a Stream object, which is what most of the articles I have found require doing.
Any help or direction would be much appreciated. Thanks
As a last resort, I can always fall back on using an NSURLConnection to do this, instead of WCF, because I know there are NSURLConnectionDelegate methods to hook into that will provide this. I wanted to avoid NSURLConnection, so that I will be able to easily drop this code into an Android project in the future.
Is there a reason to use WCF instead of the plain HttpWebRequest?
WCF is not exactly efficient at parsing data, it will keep multiple copies in memory to deserialize the various chunks of information.
There is no system level API that can provide this information, the Stream that you get back from the HttpWebRequest is the best value that you will get.
OK, I am building an application that will be using ASIHttpRequest in several places to either get JSON data from a web service or will be posting to a web service. I have it working, but really don't like having several instantiations of the request object sprinkled around the different view controllers (Login view controller, a tableview controller, and a detail view controller. I would like to move all my ASIHttpRequest methods to one class and just get back a dictionary of values that came back from the web service. The problem with this is that the delegate methods don't return that I need to have returned.
What would be some suggestions on how I can consolidate all the methods that will create an HTTPRequest and return values when the request is finished.
I can post code if need be, but this is really more of a general question and not a specific issue. If there are any tutorials on how this should be done, I would appreciate it. I want my code to be efficient and pretty :)
Thanks!
Your problem is going to be asynchronousity. I'm not sure what you mean by consolidate, but you can have a singleton (you can just use your app delegate) to call the requests. So you would do something like this:
[(MyAppDelegateClass *)[UIApplication sharedApplication].delegate doLoginStuff:(NSDictionary *)params delegate:self];
If you're doing all this asynchronously, you can't just call this method and have it return something. You'll be stuck with having some sort of callback to your view controller, which is the way ASI works out of the box essentially. At best, you can minimize the code to generate the request and set any repetitive properties.
I'm not sure what you mean by having the instantiations floating throughout. If it's memory you're worried about, it would be no different reusing the same object. ASI typically uses an autoreleased request, so it would be the same as creating it in a "consolidated" method. If it's just clean code, I would do a singleton way and maybe make a shortcut c-based method call in some type of Utilities class that you create and import in with your prefix file. But again, you need the callback methods in your view controller so it doesn't get too much cleaner than it already is meant to work. I share your pain though.
When any request comes back, I almost always have a method that parses the results. Typically I'm only working with one type of web service, so have a method that parses the results and (also logs it to NSLog for debugging purposes) also gives me back an NSDictionary or NSArray.