Setting Up the Imgur API20:48 with Jamie Huson
To connect to an API using Retrofit we create an interface that describes the endpoints. These methods describe the HTTP method we are using, URL we are calling to, and the type of data we expect to receive back.
Welcome back, we added the functionality to authorize the user and 0:00 allow our app to act on behalf of them. 0:04 So next we need to add the functionality to connect to the imager api and 0:07 get the user's currently uploaded images. 0:11 And this is where we're start leveraging retrofit. 0:15 So to connect to an api using retrofit, we want to create an interface. 0:18 And that interface is going to describe the endpoints we're connecting to. 0:23 So here I already have our imager interface, and 0:27 we're going to start adding to it. 0:30 So in here I'm actually gonna make sub-interfaces within this one and 0:34 that's because some of these endpoints we connect to are gonna require 0:37 authentication, some of them aren't, so we want to distinguish between those two. 0:41 So here I'm gonna say interface and I'm just gonna call it auth 0:44 because these are gonna be the endpoints we connect to that require authentication. 0:48 And next we wanna go ahead and add the method for 0:53 getting the users uploaded pictures. 0:57 Here's what that looks like. 1:01 First we can annotate the type that this is gonna be. 1:03 It's going to be an HTTP GET call. 1:06 So we annotate get. 1:10 Notice it's prompting us to import here. 1:12 We're gonna go ahead and do that. 1:15 Then we're going to add in the end point that we connect to. 1:20 And this is found in the documentation on the Imgur API website. 1:24 The version is three of their API. 1:30 You want to connect to the account. 1:32 And we're going to put in the user name. 1:35 Get the images for that account. 1:40 And optionally page through various pages 1:43 of images if they have a lot of images uploaded there's gonna be pages of them. 1:47 The method actually looks like this has a name. 1:52 We're gonna call images and 1:54 text we fill in those path variables user name and page. 1:58 We're going to supply an annotated path parameter here, 2:01 and we just want that to match the names that we gave them in the URL. 2:07 And this is going to be a string. 2:12 The second one Is the page number. 2:13 That's gonna be an int. 2:22 Okay, but we need to make sure that we import these as well. 2:25 And finally we need to add the return type. 2:31 So on retrofit the return type is always a call. 2:33 You can see here that it's parameterized and 2:38 the type we're expecting to get back is something called BassicArrayList=Image. 2:43 And we're gonna wanna use the image class that's in the model that I've supplied. 2:56 Let's go ahead and take a look at what basic actually is. 3:06 So if we look here in our model we can see that basic is a really simple class. 3:10 It has a status code, and a bullion indicating whether this call is 3:15 successful, and then it has some data associated with it and 3:19 this is parameterized as well so the type of data is whatever you supply to it. 3:23 In this case, I know that I want to get back an ArrayList of images. 3:28 And we can look at the image class. 3:33 It's also pretty straightforward. 3:35 It's just all the metadata that each image has when it's returned back from 3:37 the imager API So looking back here, we can see we have a complete API call now. 3:41 Okay since this is an interface, it's not an actual object we can work with. 3:49 We need something to create an object out of this interface declaration. 3:54 And that is something that we usually call a service. 4:00 You can call it anything you want. 4:03 But typically will create a class called service. 4:05 And we're going to use this to create instances of our API that we can use. 4:07 So it's going create a new class and our API. 4:12 We'll call it service. 4:14 And what we want to do here is how to method that returns back 4:22 an instance of our. 4:25 API interface that we just created. 4:26 So let's go ahead and create a new method and static, and 4:29 it's going to turn back the type that we just created. 4:33 And we'll call it getAuthedApi. 4:39 And the nice thing 4:40 about retrofit is that it has really nice builder classes built right into it. 4:45 So here we can say return new retrofit.builder. 4:50 Let's go ahead and import that. 4:55 And the first thing I wanna supply is the base URL and 5:02 we stored that earlier in our image or a class. 5:07 We wanna add a converter factory. 5:12 So this is what's actually used to take the binary data and 5:15 convert it into some object type that we can actually use. 5:18 Those are the models, image that we have in our model package. 5:22 So the one we included in our dependencies, 5:27 if your member earlier, is the JSON one. 5:29 JSON has JsonConverterFactory.create. 5:33 And this creates an instance of this converter for us. 5:37 Finally we call, build. 5:41 And then we're gonna call create. 5:43 And in create, what we're going to do is pass in what we want to create. 5:48 Which is an instance of our Imgur.Auth.class. 5:55 So this is gonna to return back an instance of our Imgur.Auth.class. 5:58 Now there's one thing we do need to add here, and that is because 6:06 in the documentation found on the website it says, for every request, if 6:11 we're authorized by the user, we need to include the access token in that request. 6:17 And the way we do that is we add a header to that request. 6:22 So the way we're gonna do that, it's pretty easy, pretty straightforward. 6:26 First we're gonna get our HTTP client. 6:31 It's the OK HTTP client. 6:34 And we're going to supply a custom OK HTTP client. 6:35 We're gonna use the builder and with the builder are gonna say add interceptor. 6:40 And here's what this is gonna do. 6:47 Every single call that goes through this instance of OkHttpClient will 6:49 be intercepted by this piece of code we're about to write. 6:54 And so for every single request that comes in, we're just going to take that and 6:57 append a new header with our access token and let it proceed. 7:01 So create a new interceptor. 7:07 And you can see here the call that happens is called intercept. 7:09 And when it calls intercept has this chain. 7:16 So there can be multiple interceptors. 7:19 Happening at different levels of the request and so 7:22 what we're going to do is we're going to call chain.request and 7:25 this is going to give us back the current request. 7:28 I wanna call it authed let's import this and 7:34 the request is now going to be added to. 7:41 And to do that, I can use a newBuilder. 7:49 And with newBuilder, it allows me to build on to the existing request. 7:52 So I'm gonna say, newBuilder addHeader. 7:56 And the header is authorization. 8:00 And the format looks like this, bare space. 8:05 And we want to add in our token. 8:13 So I'm going to call get access to it. 8:15 Finally We can build this, and 8:23 this is gonna return back a new request that is off. 8:27 That is it has an authorization header we've added to it. 8:31 Finally from this we have to return back a response, and 8:34 that is done by saying return chain.proceed. 8:37 And this will proceed to send our new request 8:41 on to the next level in the network request. 8:44 And here, instead of ending it, we're going to call build, 8:52 cuz we were working with the OkHttpBuilder here. 8:56 So call build here. 9:00 That returns back the actual client. 9:02 And one final thing is we need to supply this client in our retrofit builder so 9:05 that it's used every time we make a call here. 9:10 So here, we're just gonna call client, and supply it. 9:13 So this is gonna complete our Service class and the getAuth API method, 9:19 which will return back an instance of the interface Imgur.auth. 9:25 Okay, so we've written some code. 9:29 Uses OK HTTP client, it uses retrofit builders. 9:33 So, you might be wondering what's the difference between all this? 9:38 What's retrofit, what isn't? 9:41 Let's go ahead to talk about the differences between HTTP, 9:43 OK HTTP and retrofit. 9:48 So, http, it's a standard protocol used by all web sites to 9:50 deliver content between different clients. 9:55 So it has things like the type. 9:58 Here we have to get it's using HTTP 2.0 and it has the host this is 10:01 the API we're connecting to and that typically has a whole bunch of headers. 10:06 So these have a lot of different information used by clients to know 10:12 what data is coming over the wire. 10:16 Then there's going to be some response. 10:20 That might be a 200, that means it's okay. 10:23 That's a standard value. 10:25 Again, this is just a protocol being used, in addition to this the response might 10:28 have a number of headers as well, just like the request had. 10:32 The response will have additional headers. 10:36 And finally, the response is going to have the actual data 10:39 that it's responding with, so in this case, some Json. 10:43 And we can see here. 10:47 It has an id, a title, a description. 10:49 This is just an example. 10:52 Typically a response is much longer, has much more data involved. 10:53 So that's HTTP. 10:57 So what is oKHTTP? 11:00 OkHttp Is an HTTP stack that allows us to make HTTP calls using HTTP easily. 11:02 We can create a URL like this by just making a string. 11:10 We can create a new client and then create a new request using a builder. 11:14 Here I call get. 11:20 It's a get request, supply the URL. 11:21 I can add headers and call build to build a request. 11:23 And then I can say newCall. 11:26 And that's gonna give me back this call object. 11:27 And then I would do something like this. 11:31 I would say call.enqueue. 11:34 This is going to enqueue this call in a threading pool. 11:36 So it's going to execute off the main u.i. 11:41 thread. 11:42 And i'm going to get a callback so i supplied a callback here. 11:43 You can see I have a response and a failure. 11:46 So if i get it back it's a two hundred that means okay. 11:49 I'll get my response call. 11:52 If something happens and this fails, I'm gonna get it an on failure call. 11:55 So that's OkHTTP, 11:59 it wraps up it’s to be a protocol in some nice builders and 12:03 easiest classes, then there's retrofit. 12:07 Retrofit adds another level of easy syntax to use on top of OkHTTP. 12:12 So we can see here, instead of having to type .get, we can actually annotate 12:19 the URL and dynamic path variables and the type, all in one go. 12:23 We can also easily tell it what type of data we expect to get back and 12:30 it does the converting, using that converter factory we supply. 12:34 And then we can just create a simple, small piece of code using the retrofit 12:39 builder to tell it, all right what is the API URL we're connecting to? 12:44 Do we need to supply a custom client? 12:47 Which we did. 12:49 And it creates an instance of that class for us. 12:51 So it takes that interface, creates an instance object that we can easily use. 12:56 Finally it does return back a call the same type of call that HTTP has and 13:03 again, we can enqueue it. 13:08 But the difference here is that we can use this nice, 13:10 static method we built in our service class to do something like this. 13:13 We can say Service.getAuthedApi.images, enqueue, and 13:17 just put our callback right there. 13:21 So this is something that we're gonna add to our activity to actually call this. 13:23 And then the callback is gonna happen in our activity so 13:28 we can display the images that come back in the UI. 13:31 And again you'll notice we get the onResponse, and we get the failure. 13:35 So we know what's happening and we can respond accordingly in our UI. 13:39 Here we're back in our main activity and now we want to actually add the call to 13:45 the API that we created in our Imgur API interface. 13:48 So here we can see that in on create we check if are authorized and if so 13:54 we call this show account images so let's go and go to that definition. 13:59 You can see here that first we're just going to show the images container and 14:03 hide the sign in an anonymous upload buttons. 14:08 And the first thing we need to do here is our to do which is to actually 14:12 make this call. 14:15 So let's go ahead and we'll add a call to another method called fetchAccountImages. 14:16 And then let's go down and define that. 14:24 Okay, so we're gonna use our service class that we created before. 14:33 Service.getAuthedApi.images. 14:39 And the first thing we need to supply is that user name so let's go ahead and 14:46 use their off util to retrieve that back. 14:50 And the second thing is the page number. 14:57 For now let's just go ahead and use page zero. 14:59 That's going to be a very first page. 15:02 So this is going to return back a hold command. 15:05 Hover over here, it's gonna return back our call. 15:09 And then we want to enqueue our call and provide the callback. 15:12 So we'll say new callback and go ahead and do what it suggests us to do, 15:17 which is provide an implementation with the type correct. 15:23 It's gonna return back our array list of images. 15:27 So, onResponse is gonna get called as long as the HTTP call succeeded, 15:31 went through and connected to the API and came back. 15:36 So, it may come back and it failed in some way, according to the API. 15:40 The request didn't fail coming back, 15:44 but the API maybe didn't like our request in some way. 15:45 So the first thing we want to do is just check that our response.code 15:49 equals a known value which is OK. 15:56 That's the two hundred value. 16:01 And so as long as it's OK we know that We got data back. 16:03 That's what we wanted. 16:08 So if we do have data back, what we want to swap that in for 16:09 the adapter that's set on the recycler view in this activity. 16:13 So I've already set that up in the starter files. 16:18 So first thing I'm gonna do is just cast to the type ImageAdapter and 16:21 get our adapter from the recycler view. 16:25 And then I'm gonna call the method on it swap. 16:30 And I want to swap in the new data. 16:32 Notice that the data is already in the type I need it. 16:36 That's because retrofit converts the binary data 16:39 into the type that I need using the converter. 16:42 So here I can just say response.body().data. 16:45 That's gonna swap out these new images into a recycler review. 16:51 Now if something went wrong if there was something else that was a problem, 16:57 let's go ahead and indicate that in some way. 17:00 I'm going to make a little snack bar. 17:03 You probably wanna have some sort of prompt or make sure we go into 17:05 a state to allow the user to retry this or maybe retry yourself a few times. 17:10 But for now I'm just going to go ahead and supply a snack bar to just indicate 17:15 visually in the UI if something went wrong. 17:20 I'm gonna say Failed and provide a little sad face. 17:28 Finally, don't forget to call show and 17:35 I'm going to do the same thing if a failure case happens. 17:38 So, a failure would call back to onFailure, 17:43 if the call was unable to complete in some way. 17:48 So if the call does complete in some fashion, maybe the code's wrong or 17:51 we requested something incorrectly. 17:56 But it does complete. 17:58 It'll come back to onResponse. 17:59 If it fails in some way 18:01 trying to transmit the data over the wire it's gonna come back to onFailure. 18:03 Now finally it's important to note that when we call enqueue and 18:08 we provide this callback, this is going to happen on the main UI thread. 18:12 The call itself will happen on another thread, which is what we want. 18:16 But we can interact here, for instance, 18:20 with our adapter because we are on the UI thread. 18:22 One more quick thing we're gonna do is just add in another snack bar to tell us 18:26 that we're getting the user's images. 18:29 So we'll say Getting Images for Account and 18:34 that'll just provide a nice UI so we can know when this request starts. 18:41 Ok let's go and run this and see this in action. 18:47 What we should see is that when we run it we're not authorized. 18:51 We're going to need to authorize our app, get a call back into our app, and 18:54 then make this call to fetch image accounts. 18:58 And when we come back up here what we'll seen on resume is that 19:02 If it is authorize show account images should be called. 19:05 And that will in turn call fetch account images and 19:09 we should get those images displayed back to us. 19:12 So let's go to run this. 19:14 And run this on our device switch over to our device now. 19:21 And our app just started. 19:36 First thing we'll see is we have the sign in button. 19:37 The upload anonymous image button, we'll get back to that later. 19:39 First thing we want to do is we want to sign in and 19:43 authorized user and authenticate our app for the user. 19:44 Go ahead and click sign in. 19:49 Remember this can take us to the image or API website where we need to log in. 19:51 So here log in with your account and click allow. 19:56 I'm gonna go ahead and log in with mine now. 19:59 Okay, so once user signs in it's gonna open this prompt with the url 20:06 that's coming back to our apps so we wanna go ahead and use our Retrofit workshop. 20:11 And you can either say just once or always. 20:17 For me i'm just gonna say always. 20:21 Here you can see it said we are getting images for this account. 20:28 And lo and behold the images appeared. 20:32 So our API call succeeded. 20:34 And we got the images. 20:37 So this looks pretty great. 20:40 In the next video, we're going to go ahead and fill out the functionality for 20:42 this bottom Upload Image button. 20:46
You need to sign up for Treehouse in order to download course files.Sign up