AnthonyMDev / AmazonS3RequestManager

A request manager that uses Alamofire to serialize requests to the AWS S3 (Amazon Simple Storage Solution). Based on AFAmazonS3Manager

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Parse Amazon S3 Responses

AnthonyMDev opened this issue · comments

We should implement response handling to parse the Amazon S3 response.

An extension on Alamofire.Request that adds a responseAmazonS3() function seems like a good way of doing this.

0.7.0-beta.2 includes a simple data response serializer that parses Amazon S3 Errors.

I'd like to add serializers for custom ACL responses and custom serializers for common data types that parse AmazonS3Errors.

I'd like to work on this since I desperately need this functionality. Which branch should I use as a starting point? And one concern: An extension on the Request class as you did seems a plausible way to achieve that. However, If we do that, we will have to call the dedicated serialiser method on the completed request depending on the return type. Like request.responseS3ListData(…), request.responseS3MeataData(…) etc. How about we create subclasses of Request like ListRequest and override either response or a dedicated property like s3response. Like this on the usage side we can ensure that the correct serializer is called. Let me know what you think.

@sbhklr I see what you are going for, however I think that we should still with the custom serializer methods. There may be instances where the user does want to get the raw response data, or serialize it in a different way. By overriding response(), we take away that capability.

This is the method that Alamofire recommends and supports. Subclassing Request may lead to incompatibility issues in later versions of Alamofire.

@cnoon: What are your thoughts on subclassing Request vs. creating custom serializers? Do you see this causing other unintended consequences?

@AnthonyMDev I see your point but instead of overriding response() we could still create subclasses and override a custom property like s3response. This should be safe. The problem there is that it's probably hard to find a function signature for s3response that suits all use cases. For example listBucket() should return a list of filenames while getObject() should return data. The advantage with the current approach is that adding serializers doesn't break API compatibility with version 1.0.

@sbhklr I do see why that makes things more elegant.

Here's another thing to consider, when using the AmazonS3RequestSerializer to create NSURLRequests but not using the AmazonS3RequestManager, you can send these requests to a regular Alamofire.Manager (or any other networking library for that matter). Using the default Alamofire.Manager won't return our Request subclass, but I'd still like users to be able to serialize the response using our custom serializers.

What if we created custom serializers, and also created custom Request subclasses. On our subclasses, we can create a new func for s3Response that uses the custom serializers. The AmazonS3RequestManager can return our new subclasses, while still allowing regular old Request objects to also use the custom serializers.

With this approach we maintain the flexibility of custom serializers while giving the elegant API that you are seeking as well.

Sounds reasonable. I'll give that a try tomorrow.

@sbhklr Thanks for taking this on!

Hey @AnthonyMDev, definitely don't subclass. You can't anyways b/c the init methods on a Request are internal. You wouldn't be able to make a subclass instance with Alamofire even if you wanted to unless you made some much bigger changes to Alamofire itself. Instead, use the extension approach and add a custom serializer.

In order to mitigate the need for multiple serializers, you could always pass an enum case into your single S3 response serializer that specified what the expected response was. This would allow you to use a single response serializer for all the different types of responses. It would be very similar to the concept of validating a response status code.

Hopefully that helps.

@cnoon Thanks for your comments. I didn't even consider the initialization of the Request.

@sbhklr Looks like we have to go with custom serializers.

@cnoon @AnthonyMDev I don't quite see why this shouldn't work. Subclassing Request works for me. At least it compiles so far. And the instances of these subclasses don't have to be created by Alamofire but only by AmazonS3RequestManager. They would use the according serializer that still can be implemented as an extension of Request. The whole purpose is to provide the user of AmazonS3RequestManager with an API that ensures the usage of the correct serializer.

@sbhklr I'll check out whatever you come up with. Either way, I definitely think that we need the custom serializers. We know we can use those either way.

If you can get the Request subclasses to work, I'll check it out. I'm not sure how you are initializing the subclasses though without access to the initializers. I'm still concerned about the unintended consequences of subclassing Request. Especially after:

definitely don't subclass. -@cnoon

You might want to do the custom serializers in one PR and the subclasses in a second PR, that way we have the ability to merge the serializers themselves if the subclasses don't work out.

I think we can close this issue. The serializers work.