Basic GET request demo0:00
Laravel 7 includes a new HTTP client that I think you're going to love. Let's start with some kind of demo API. Let's hunt one down. How about this? Yeah, just some fake data. API/users. That's what we want. So let's switch back, and we'll say, after I import it, make a GET request to this endpoint, and we want API/users, and we'll give that a run. So we get a HTTP response. Now, if we quickly take a look at that response, here's all the methods we can call. Get the string body. If it's a JSON response, get that. Get the headers. Check if it was OK. Check if it was a redirect. Check if we have a server error, a 500 error. Lots of different things. So in our case, I want the JSON response.
Check if it was a redirect. Check if we have a server error, a 500 error. Lots of different things. So in our case, I want the JSON response. So we give it a run, and sure enough, there we go. So now it looks like what we want is the data. So why don't we grab that? And there we go. You have your list of users, and we can even wrap it within a Laravel collection, and we're all set to go. Really nice. Now, behind the scenes, this is still using Guzzle, but it's effectively a wrapper around Guzzle to make these things really easy to accomplish. Let's see what else. One more. How about we make a POST request, and we need to give it a name and a job.
Sending POST requests1:14
Let's see what else. One more. How about we make a POST request, and we need to give it a name and a job. So now we make a POST request to api/users, and we can send through the POST data here. Now, often as part of this request, you'll want to pass through specific headers, which you can do here. You can simulate a form request in certain situations if you need to, but in our case, all we need, if I switch it back, is the name and the job. And now, if we come back, give it a refresh, once again we get that response. So why don't we start by checking out the status. All right. A 201 created.
Calling GitHub API1:49
So why don't we start by checking out the status. All right. A 201 created. We could check if the request was successful. In this case, of course it was. We can get the body of the response, which is basically the stringified version of the JSON. But yeah, in our case, once again, we want the JSON output. And there we go. All right. So now, if we were to use an actual real API, how about one I know off the top of my head is GitHub's API? So, for example, I could grab users, let's do Laracast, and let's grab the JIS for Laracast. All right. Give it a run. Once again, we get a response.
So, for example, I could grab users, let's do Laracast, and let's grab the JIS for Laracast. All right. Give it a run. Once again, we get a response. Let's check the status of it. All right. Looks like we're good to go. So let's grab the JSON output. If you can see, here's all of the JIS. This looks like for one of the katas, a player and a tennis match. But now you'll notice for each JIS, you'll see an HTML URL, as you see right there. Okay. So why don't we grab only those? What we might do is grab that, and then we will wrap it within a collection, map over it,
Okay. So why don't we grab only those? What we might do is grab that, and then we will wrap it within a Collection, map over it, and for each one, yeah, all we really need here is the, at least for this demo, is the HTML URL. Give that a run. And now, let's clean this up a little bit. Anyways, this includes a brand new Collection of only the JIS. Now, of course, if we're using PHP 7.4 or higher, we could swap this out with a short function, or short closure, and that'll just be something like this. Give it a run, and of course, that's still going to work. However, maybe you also have a custom JIST class that you want to map to. Let's quickly do this. I have a little shortcut here.
However, maybe you also have a custom JIST class that you want to map to. Let's quickly do this. I have a little shortcut here. Run that. Pretty simple stuff, but now we're going to return a new JIST, and we're going to pass in the URL. Give it a run, and now we have a collection of JISTs. And now any extra functionality can be appended to this class. All right, maybe one or two more things, and then we'll call it a day. So yes, I can fetch the public JIST for any account here. However, if I have an authenticated User, I could just do /JIST. Now, if I don't have an authenticated User, you'll see it's going to give me all public JISTs,
Adding API authentication4:03
However, if I have an authenticated User, I could just do JIST. Now, if I don't have an authenticated User, you'll see it's going to give me all public JISTs, so I didn't create any of these. However, if we pass the correct authentication, so let's go to facades, let's go to that HTTP facade that we're working with here, and you'll see here's where we can specify our auth. Basic auth, encrypted auth, or we could send through a token. Let's use the token route. That'll send through the bearer token. Okay, let's say with the token that you can generate through your GitHub dashboard, I have a temporary one that I've created just now,
Refactoring real controller4:35
Okay, let's say with the token that you can generate through your GitHub dashboard, I have a temporary one that I've created just now, and if we give that a run, now you'll once again see I get my JIST specifically. So that's how you can provide authentication. Okay, last thing. Let's finish up by looking at a real example. So I have a PodcastController. Now, this corresponds to the podcast page, Alerikas, and it's really simple stuff. So notice I accept Guzzle as a dependency. We load a view, and we fetch the feed, and this is it. Again, so simple.
We load a view, and we fetch the feed, and this is it. Again, so simple. We make a request to Simplecast. That's who I use. I pass through the API key. We make a request with Guzzle. We get the body. We decode it. That's always kind of clunky with Guzzle, but that'll give us our feed, and then I map over that feed and return a new Podcast for each item, and that just contains extra helper methods that I use in the view. So, for example, if I were to just dd(fetchFeed), and temporarily let's get rid of the caching so you don't have to see it.
So, for example, if I were to just die and dump, fetch feed, and temporarily let's get rid of the caching so you don't have to see it. Come back. Sure enough, we have a collection of podcasts, and then I cache them for a little while at a time. So let's see how we might update this for Laravel 7. I'm going to scroll down here. We're no longer going to use Guzzle directly. Instead, I'll pull in the HTTP facade. And remember, this is still entirely testable. So we're going to make a GET request to the URL.
And remember, this is still entirely testable. So we're going to make a GET request to the URL and then grab the JSON response. So if we did nothing else, this is equivalent to this. Come back. Give it a refresh. As you see there, it still works. Okay, great. So now I no longer have to depend on Guzzle as a dependency. I can get rid of that. Next, because this is much more simple to prepare,
I can get rid of that. Next, because this is much more simple to prepare, I might inline it. And yet again, if I'm using PHP 7.4 or higher, I can switch this to an arrow function. And at this point, that's a little long for my taste, so often I will do things like this just to clean it up. And there we go. We're good to go. Okay, so finally, one last thing. I know I said we were done, but we're not.
Faking HTTP in tests6:44
Okay, so finally, one last thing. I know I said we were done, but we're not. In terms of testing, of course, like many of the other components, you can fake any HTTP request. So if I added this and nothing else, any request will be faked, and I'm not actually hitting this endpoint. So you never have to worry, well, I'm using this facade directly, which means you can't mock it or stub it out later.
well, I'm using this facade directly, which means you can't mock it or stub it out later. Yes, you can. It's actually really powerful. You can fake it. You can stub out a sequence of responses. You can do quite a bit, actually. We could even say, well, here's specifically how we're going to fake it. When you make a request, I want to return a custom response.
When you make a request, I want to return a custom response. We'll just say foobar in this case. And again, this can be useful in your tests. So now I give it a run, and regardless of what I request, I'm actually going to get this instead. So now you can use this in your tests. You can say, all right, I'm going to fake my HTTP client,
You can say, all right, I'm going to fake my HTTP client, I'm going to hit this endpoint, and then I'm going to assert sent, and this will accept the request as well as the response if you need it. Here's where you can assert maybe the correct header is passed or the correct endpoint or the
maybe the correct header is passed or the correct endpoint or the correct authorization. So, of course, if you are posting data, you might say, well, check if the user's name matches up or some kind of attribute. This is not quite useful, but in our case, we can check if the response foo bar just has a quick proof of concept,
if the response foo bar just has a quick proof of concept, and that works. But if we were to change it, of course, we'll get an ExpectationFailedException in your tests. All right, and that's basically it. So if there's anything more specific, of course, check the documentation, but this is a welcomed addition to Laravel 7.
is a welcomed addition to Laravel 7.
