Image for post
Image for post

Protocol-Based Generic Networking -Part 2 JSONEncoder and Encodable for Post request in Swift.

Its been a while since I wrote “Protocol Based Generic Networking using JSONDecoder and Decodable in Swift 4” on that post I talked about how to use Decodable, protocols and generics to create a reusable networking layer.

It worked great but the API was limited to the GET HTTP method, that's why on this tutorial I want to extend it to use the POST method, I will do my best to show you how to use enums to do the job, I will assume that you didn’t read part 1 so I will start from zero in a new project and you can always go back to the first part for more details.

We will start with the GenericAPI class, create a new file and copy and paste…

This protocol extension contains all the code needed to create a task that retrieves the contents of a URL based on the specified URL request object, also instead of serializing the response, it decodes it using Decodable protocol (again I suggest going to part 1 for more details).

Now you should have a few compile errors and that's because you will need to create a few classes, let's start with the APIError, create a new file call it APIError copy and paste…

Here we start using enums with associated types to construct a specific type of error, now let’s construct another enum, this time it will hold two cases, one for a successful request and one for a failure case, create a new file and name it Result…

If you are not familiar with this syntax I suggest to read about generics on Swift there are great tutorials online for starters but if you are familiar already with generics and want to see a more advanced usage check this post out.

Ok, now let's create a model for our HTTP methods, create a new file and call it HTTPMethod, there are others HTTP methods than “GET” and “POST” but this tutorial is focused on showing you how to use Encodable to use “POST” so will keep this model simple…

As you know you will need to pass some type of headers to your request in a POST method so let’s create a model that handles that, again new file…

For a full list of HTTP headers check this link you can extend this enum with the full list!

Ok, now we need an endpoint, I really liked the approach of using an implementation that I saw on Treehouse, handling strings with different endpoints can become easily a mess so by using this protocol extension we, later, use an enum to manage all those endpoints in one place, create a new file and call it Endpoint….

Here, we just construct an endpoint with a base path and the path to direct the request, if you already saw part 1 I apologize that most of the content so far comes from that tutorial but here is the good part, lets add a function that will construct a POST request, inside this protocol extension add this function…

Oh man I love generics, protocols and enums, they really help reduce code duplication, let me show you why, the parameters parameter in the function signature is a generic type that conforms to Encodable, so it can accept any type of model as long as it conforms to this protocol, this way we won't need to create a new different function for each different model, the headers parameter its an array of HTTPHeader objects which is the enum that we create a few moments ago.

Inside the function we check if there is a request then we use the HTTPMethod enum case to define the httpMethod in the request, later we use JSONEncoder to encode the model, and finally we perform a for each to add the HTTPField and its corresponding value to the request headers, all done! this is all that we need, so how you will use it? well I apologize but for simplicity I won't use any API to perform a real request however I will show you how to use it step by step, let’s say we are using an API to retrieve your favorite show on Netflix, mine is Narcos (very excited for coming season 4 BTW) anyway so here is how the object that will conform to Endpoint will look like….

You get the picture here? let's say now you want to add “politics” to your API you just need to add a new case and its corresponding path, ok let's say that our APP let the user search for characters of the show, first you will need a model that looks like this to decode the response…

Then lets say the API that fetches characters uses a POST request that takes as a parameter an ID that can be a name like “Pablo” it also needs the “Content-Type” key with “application/json” value for the headers, so you will need an object to encode the needed parameter, it can look like this…

Now, you are going to need to create a Client that conforms to GenericAPIClient protocol and inside it create all the functions needed for the data that you need for your app, it will look like this…

Inside the fetchNarcs function, you can see how we use all the components written before, the request is constructed using the corresponding path “/narcs” and then the function in Endpoint protocol takes the parameters and headers.

Finally, this is how a typical call to your NarcosClient will look like…

Now you can see how the Result enum can easily help us determine the state of the request and act accordingly.

I hope you find this helpful, and again if you already read part 1 I apologize for the duplicate content but it really helped me explain how to create a POST request following the same approach on the first part, you can find the full example for this tutorial on this repo.

Thank you!

Written by

Senior iOS Engineer #latinintech

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store