 and let's hope my stream deck plays nicely. There we go, lovely. So yes, as you heard from the intro, hello everybody. I am Jim Second, I'm a developer advocate at Cloud Communications Platform Vonage. So if you want to know a bit more about what we do at Vonage, we've got a sponsors room, so head to the sponsors room. Importantly, we've got a code that you can use to get some free credit if you want to test out our, if you want to test out our APIs, if you want to test out our voice APIs, SMS, WhatsApp messaging, things like that. We will have Cloud Communications Platform for that. And we have a more importantly for people, we have a raffle. So if you want to join the raffle, sign up for the service and you've got a chance to win some headphones, which is all very fancy and all very cool. Now, I was introduced obviously that PHP was mentioned a lot. I am the PHP developer advocate at Vonage, but that's not all I do. And the important thing is for anyone who thinks this is a PHP talk, it's not. And you'll see why it's quite cool. So yes, here are my, here are my, is my stuff, if you've got any feedback or you want to, or there's any, we run out of time for questions or something like that. I'm very active on Twitter. I've got a LinkedIn and like every good developer, I have a huge GitHub graveyard of unfinished side projects. And as mentioned before, I am the PHP advocate at Vonage. So let's get started. I'm just going to give an outline. I'm going to give an outline on what, this is how this came about. It's sort of a mini story at the start of it. And what came out about it and how I'm going to tell it. So first things first, hopefully something we can all agree on. Test the external APIs that your software relies on. It's hard, right? That's not that controversial. It's hard. Your software uses another API, right? You have no control over that API. You've got to test it. How do you do that? I found something. It's a library, found it. Tell you what, it's not even cutting edge. It's not even new. It's just it's been going on for, old tech it's been going around for ages. So I thought, okay, give it a gun, check it out. And the conclusion is, oh my goodness. What is wrong with us? Why is everybody not using this? Everybody should be using this. We've got it all wrong. Whatever you know, it's all wrong. It's all wrong. We use this. I'm being, of course, a little bit dramatic because I have a dramatic background but this is what it sort of looks like. So I'm going to talk about how problems come about when you have external API dependencies and what the library is that I found and what it does, when to use it, how to use it, should you use it? Because, you know, as always it depends. Right. I wonder if anybody in the audience knows what this is or this is point the right way. This is a beta max tape, a closed proprietary format introduced by Sony. It was technologically quite superior for its time and a very interesting fact for you. The last ever beta max tape was produced in March, 2016 which is ridiculous. That's how long they're actually being produced for. On the other hand, this is something that people might recognize more. Well, this is something that people over the age of 30 might recognize more. This is an open format. This is Fossasia, after all. An open format called VHS, which was designed by JVC and was adopted by Mitsubishi and Hitachi. This was technologically not as superior as the beta max format. It wasn't as good, but it was an open format which meant that it was adopted widely and it absolutely killed beta max. And there is, there's a story there, I think, behind things. So because, you know, I know what you're all thinking. You're all thinking, come on, Jim. Is this really relevant? I thought we were talking about APIs. What's going on? What's this? And the answer is, of course, yes. Why else would I be talking about it? Of course it's relevant. Oh, God. Oh, hard to please. Oh, look, and VHS came out first too. So that's an interesting fact that I didn't know about. Anyway, yes, it is relevant. I mean, sort of, sort of, you know, a bit, what I'm trying to say here is like, it's a tenuous link, but I've got to get your attention somehow, right? What I'm trying to say, what makes this relevant is this very important message, which is sometimes the most practical solution in software is the best one. Beta max was the correct option because it was technologically superior, but it wasn't the best one because it wasn't the most practical option, which leads me onto bug bears about software development I have. And this is the biggest one, first of all, which is this quote. Oh, don't muck what you don't own. Look, do you know what, when I hear this, when I hear this as like a staple in the software industry, don't muck what you don't own. I think of a film from 1998 called The Big Lebowski and it takes place in a car and the scene is wrong. Wrong, you're not wrong, Walter, you're just an asshole. And it's so true though, isn't it? Don't muck what you don't own is like, it's not wrong, it's correct, but it doesn't make things easy, right? We have things hard and not being able to muck something that you actually rely on is like difficult. So, what I'm trying to say here is that we already have the tiptoe around external dependencies. This is, I come from the PHP land, but if we're starting to get to node in JavaScript, people who use those ecosystems know what NPM is like, right? You're downloading thousands and thousands of other people's code and libraries. This is why we need tooling. And given how difficult it is and we have to solve so many problems, it leads beyond to my second bugbear and this is a bit different because I have respect for, I have respect for don't muck what you don't own, but this, something that I hear all the time. We don't have time for testing. Who says this? Oh, we don't have time for testing. If someone says this, if a company says we don't have time to test our software, I think clowns, absolute clowns. But it's a bit, it's not very helpful to just say, you know, people are idiots. Let's look at why that quote comes about. Why do people say we don't have time for testing? I'll give you a real world example from something that I worked on maybe about three or four years ago. So imagine you have a thing. Let's say you're building something for Shopify. So it's a cloud-based platform. You have no control over it. You have access to all of its API. How do you build and extend off Shopify when you do it via its API? So I have something locally. So in this case, I've said Symphony Framework could be anything, could be Flask, it could be Django, it could be Express, I don't know, any kind of full-stack framework, right? And the way you communicate and extend off Shopify is you use the API. And then if you want to take states out of Shopify, you store the state locally and you sort of amalgamate to the two talking through the API. So how do I test this? How do I write this? How do I write my service and I want to test it? Okay, well, the industry norm seems to be, well, we need to separate out. If you're gonna test it, you can't talk directly to Shopify, right? Any more, don't mock what you don't own, right? So you're not getting control Shopify there, but you can't own it. So you need to ring fence the API and then I'm going to use PHP unit and PHP spec for sort of for mocking. So for anyone else, this is like Jest or it's like R unit for, sorry, R spec for Ruby. This is the testing run, right? So how do you mock the API responses? Well, what you seem to do is you create static fixtures as like JSON. You have like a whole load of fixtures in JSON files, right? And then that's what you're testing against. Okay, fine. So what happens when this happens in Shopify? Yay, API change. And then you've got your API change and it's so bad that it's in like WordArt from like 2001. So if the API changes, then what happens to the JSON? The JSON is now like totally, totally wrong because it's not the, like, if you haven't got an API change that has been documented and you didn't expect it, therefore your responses are wrong and therefore PHP unit goes, I don't know what's going on. And then Clippy appears and then you have a trash fire which is a burning thing with bananas and... It's all wrong. It's all wrong. Just forget about it. And that ladies and gentlemen is why people say we don't have time for testing is situations like that. The talking of situations like that, I'm in that situation, right? I have exactly the same problem at Vonage. I'm responsible for the PHP SDK libraries. I if you want to talk to Vonage and you're a PHP developer, I maintain the open source library for it, right? So what happens is you have to talk to Vonage's APIs. How does it do that? Exactly the same situation. But being a center of excellence at Vonage Engineering, I'm not just going to say we don't have time for testing because that doesn't work. So you've got to have some sort of solution for it. And this is how the solution kind of came about. I work in a multi-language team. There's a Python advocate. There's a Ruby advocate. There's a Node advocate, et cetera, et cetera. So I was talking to the Ruby advocate and the Ruby advocate Carl goes, he says, oh, I've got a solution for you. Why don't you just use VCR? And I'm like, oh, you know, I could try that. But what? No, hold on. Stop, stop, stop. Go back. What do you mean use VCR to do the testing? He's like, yeah, it's in Ruby. It's called VCR. What it does is it records all of your APIs and then plays it back. And I'm like, okay. Yeah, but there's not gonna be a PHP one. And he goes like, eh, hold on a sec. Yeah, here it is. And just like that click, I was like, what's this? What is this magic? And I checked it out and I was like, oh my goodness. Why are we not doing this? So let's talk about what it does. What does it do? So imagine we have our brand new NICAM Matsui, digital VHS recorder, Matsui being a British company that tried to pretend to be Japanese because that's what it was like in the 90s. And you presumably want to try and set up your auto program record, which was something that seemingly never worked. And what you do is the API is what you're recording. So we pop in a cassette of our limited edition Jurassic Park, sorry, not Jurassic Park, sorry, our Vonage API. You plug it into the cassette, you run your unit tests, you press record, it records it, and then you take out the cassette and you put it into your API library of all of the things. And then when you want to run your unit tests, you pop the cassette back in, press play, and that's it. And what you've done is you've cut out the API. Okay, that's pretty cool. How does it do that? This is stuff to do with PHP, okay? So what it does is anything that goes over curl or if you're a masochist soap or the streammapper, it intersects it, right? But how does it do that, Jim? And the answer to that is, okay, look, please don't ask me how the author's got around Ruby's monkey patching to do this because it's probably voodoo leaves and chicken bones and things like that. The answer is technically under the hood. It's very complex and I don't know quite how it works. But how does it look? So it's got a base Singleton client. It's got a storage path. It's got a storage format, a mode, an on, off, and eject, right? And this is what it looks like in code. So you've got a base Singleton client in PHP. There it is, VCR class. If you use the configure method, it returns back a VCR configuration object and then you have all of your methods available on it. So in this case, you use set path and that's where your library goes. Storage format, you can choose when you record to store in JSON or you can choose XML or you could choose YAML. The mode is important. This is when you're like doing record or you're doing playback and it looks like that. So you've got set mode, new episodes, that means it will record everything. Or you can go to set mode to none. If you do that, that means that when you run the unit test, it will do it, it will put it into play. You have VCR turn off, turn off on and off and eject. Eject saves the cassette when you're completed, right? Very important that you have turned on and off because that's you're in control of what parts of your test suite you want to be recorded or tested. So that's how the code kind of looks, right? So a real-world example, how does it look with the testing? And this example is, yes, it is PHP but might look familiar to JavaScript developers. It uses what's called the PEST testing framework which is not quite the default testing framework for Laravel yet, but it will be. It's a testing runner that's designed on JavaScript's Jest framework, which is why the API kind of looks like this. So this is a live test. It will send an SMS to a live server at Vonage and then we expect the response count to be one, i.e. you've sent it and then we expect the status to be zero. That's a live test. You don't want to run that all the time because if you run that all the time, it will cost you money every time you do it and you don't want to do that in your CI and pipeline whenever you've got GitHub actions running every time, right? That's not what you want, but that is a live test. So what I did is I took a functionality specifically to do with PEST, right? You have a traits function or users function and this was built for things like, this was done for things like for unit tests when you need to do migrations, right? You want a fresh database for every single unit test you do. So what I did is I added those VCR methods into the traits. So now you can have like your set mode or your on and off wrapped around and that will now run as part of the test before every single test. So how does it look with VCR enabled? This is the same test, but now you can see you've got this switch VCR to true, now set VCR to new episodes. If you run this, this will record and then it will eject the tape and it will save it into the file system. This is how it looks. And as you can see, for those of you familiar with things like Insomnia and Postman, it looks very similar to that. It looks like an HTTP wire request, right? There's nothing sort of that mysterious about it. That's your recording and it says, here's everything I've recorded. It gives you all of the headers, it gives you everything, right? And when you want to play that back, we've put switch VCR to true, load in the cassette that we saved, set it to the play mode and now the live test exactly as it was before will no longer talk to Vonage. It will just play back what you've recorded. That is absolutely ridiculous levels of power that you can have. So reasons why you should use it. Cassette libraries of API changes versus your external dependencies documentation. This is quite a cool kind of, quite a cool thing. It sort of goes a bit like this, right? So documentation needs to be up to date and it sounds ridiculous, but how many times have you coded with an external dependency on something and it's documentation is not up to date or something has been launched and it's not been documented yet, how it becomes a sort of a chicken and egg situation, right? You don't know, you don't know what, you don't know if you update the API, what we try at Vonage is we try and update the API at the same time, but sometimes that doesn't happen. Whereas if you use VCR, you have a single source of truth for your application and your developers. It takes out the kind of human documentation element. The documentation, yes, it needs very important at least to be there, but for what you're developing at speed, you actually have something that's more concrete. But what if your external dependency, what if they accidentally ship something or what happens if they break their semantic versioning that they have where they've accidentally had a backwards compatibility break? They could do that. There's nothing, you know, the problem is it's in their hands, whereas with VCR, it brings it back into your hands. The cassette libraries by saving document, like saving all of these cassettes as recordings, it moves the dependency from them to you. So that's why I would advocate for it as something that's very, very powerful. And similarly bug turnarounds and visibility. Now this is crazy, right? Here's an example, right? GitHub issue on your library or your project pops up and you go, okay, fine. It's because it's relying on a third-party API call and it's broken. Right, I'm gonna run the project locally and then I'm gonna tell it to record a new cassette. And now I'm gonna play it back with my test runner and bingo, the power that a developer can use for has a finding an API problem like that because the test suite has failed because you've updated what's going on with the external API. That's a fairly kind of powerful use case for using something like VCR. Another one, speed. There's a bomb on your boss, full credit to Keanu Reeves is acting. Do you remember before where we said we don't have time for testing, right? And I've just said, I tell you what, if you use VCR, speed becomes something that is in your hands. And here's an example of that. This is another thing which is like, here I'm going to show you the superpower of this library. So, build me the thing, Jamie. I've just chosen Symphony Framework or I could choose Laravel or I could choose Django or Rails. I don't know, whatever, build me the thing. Okay, here's the thing. The thing requires, it relies on an external vendor API as Facebook or Shopify. I don't know, some sort of big thing or Twitter, right? And that logo is for the open API spec. If anyone wants to know more about the open API spec, we're big into it at Bonnage Naturally, ask me about it because it's amazing. So it relies on this external API, right? So what you need to do is set up the vendor account and then you're just going to write the tests in your product and then hit record whilst it makes all the API records. So then you commit the tape into source or S3 or something like that. We'll get onto one of the downsides in a minute about storage, but you commit it and then go ship it. You've just created a piece of software that relies entirely on someone else's API. You've done it at speed with full test-driven development from using that library. And that to me is stumps. That's amazing. That kind of power really did, that's the reason why I just said, why aren't more people using this? And because I am a man that is approaching my forties, I like offline stuff, right? But it is important to notice this speed. It means that you don't have to, you don't have to make all those API calls all the time. You record them once, but it means you've also got potentially offline development. That's pretty powerful. Much better back in my day. Look at that Amiga, beautiful piece of kit. Old man yells at cloud, et cetera, et cetera. But as an advocate, it is my job to not just say you should use this thing. You also need to know about why you shouldn't use it because there's downsides to everything, right? This is a big one, external production vendors. You're relying on someone else, but what about the accounts and things like that? And maybe you can't set up a staging environment with someone else's thing. It might not be possible, which kind of brings in another aspect, security. You've got to think about how you organize your secrets and your environment variables. Real big thing here is third party data. You're making calls for external service. Can you set up fixtures and things like that? You've definitely got to make sure that you don't have any live data in there. Otherwise, the live data will make it into your local file system and record it in a cassette and you really don't want to be violating GDPR rules. That's in the UK, sorry, in the EU, but it's probably different out of the APAC. Maybe you can't set up a staging environment and also if you accidentally trigger something where you put record, it might cost you loads of money. What happens if there's 5,000, 10,000 tests and they're all making API calls? You're going to have to stage that and control it. And if you don't control it, someone accidentally runs the pipeline and then it makes like 10,000 API calls. That's going to cost you money. You've got to lock these things down. So it's something to think about. And another big one is in your library, you've got to organize your library, right? So you need some strategy about how you do it, about how you name it, about how, where you store it. And also your software might already have some CI pipelines and it does some fancy stuff, depending on git tags or something like that. It means that you have to work around a solution on how you integrate this into your software. But yeah, the top thing to take away from this that I think is absolutely amazing is, like I said, you might have thought this is a PHP talk. And yes, I'm a PHP developer, but it's not. This slide is kind of unique to FOS Asia because it's about free and open source software is this slide is the money shop, right? There's no sort of better way of putting it. It's not a PHP talk because I found implementations in, get ready for it, everything. There they all are, take a screenshot. If you want to use VCR, it doesn't matter what backend you use. There's one for Golang, there's one for Java, there's one for .NET Core, there's also one for C-Sharp, if you want to use C-Sharp in .NET. There's one for Node, there's equivalence of all of them. And that makes me realize, first of all, how powerful is software? And then secondly, I really don't understand why this is almost like not an industry norm, okay? So the conclusions, whilst I motored through this talk as quickly as possible. The conclusion to draw really is, first of all, make sure it fits your use case. As an engineer should say, it depends because it might just, this thing might not be applicable for everyone, right? And also we're all talking about your software relying on external APIs. Not everyone's software is going to be relying on external APIs, you know, something doesn't. But make sure, have a look at it first and make sure that it fits your use case of what you're doing. But in my case, it fits my use case for the libraries that I maintain. And so I'm now starting to refactor all of the open-source libraries that we have at Vonage, the ones I'm responsible for in order to use it. So that, big win, yay! But for that contribution for open-source ecosystems and how they work, it's very important that I sort of build on top of that. So what I decided to do is, I decided to create an integration to make sure that if you use Laravel and you use the test testing framework, I'm going to create like a plugin for it so to integrate it as part of, so make it part of your call Laravel installation. I don't know how long that will take, but it's definitely something that I think people are kind of asked for. So that's my very sort of brief introduction to PHP VCR. Thank you very much for having me. And hopefully in a second, the MC will pop up again. I was about to answer the questions in the chat, but Clarice, our community manager, is about to, I think, about the winner for our headphones. All right. Yeah, so I think, so we have one question here. I think it's not very clear to some people in the audience what exactly PHP VCR is. Could you summarize what it is? And like... If you have software that talks to other services, that uses other people's APIs, PHP VCR will allow you to record all of the responses from that API so that when you test your software, you don't have to make the calls anymore. You have it stored locally within your software. That's the really brief intro of what it is. Yeah, thank you very much. That makes a lot of sense. I have one myself. So you talked about offline, I'm personally a robotics guy, so we're dealing a lot with the different vendors of robots and they all have different APIs. Do you see this can be used in an environment like that? Like with like, because this seems to be like web oriented or at least the initial, what it comes from and what it's been mostly used, right? But do you see that if this can be used with APIs from robots or APIs from different kinds of software that are not like web frameworks or like web development stuff? Yeah, it could be used. I think it's kind of a difficult one. It's VCR by its nature because it's recording web calls. It's very much designed and aimed at about a full stack web development or web application development. But on the other hand, the thing is if you use something natively like React Native or Python's kind of like, or Python's compiler into sort of into Linux desktop apps and things like that. I mean, potentially you could still use it because in PHP is a web language only, right? So I mean, people try to port it locally to desktop development, but it doesn't work. But Python can be used for that, which means if you had a desktop application that did make external API calls still over the web, you could still use it within like a compiled app. I see. All right, yep. And then we have another one saying, is there any chance to see VCR web RTC replay ability if it's not there support already? Sorry, can you say that again? That VCR web RTC replay ability, if not supported yet already? I don't know the answer to be honest. I don't know, in terms of video, I don't know that much. I've only just started getting used to sort of web RTC. We've got libraries that use them natively, but if you have VCR, because VCR all it's doing is recording HTTP wire calls and their payloads. So it would probably be, if you're trying to record like web RTC interactions, you could do it if it was as long as it was using HTTP, but the only difference is that it would be probably a bit too expensive to use, like it'd be making like hundreds and hundreds of calls. But it could potentially be used. I see. Okay, I think that's all for questions. Maybe if there's some more, we can... The actual building on that question, sorry. I didn't realize that it actually relies on UDP under the hood. So the answer is no, but someone's probably ported it. Okay. All right, yeah. Yeah, so thank you very much. Very interesting talk, very interesting technology. And I very appreciate all the amazing images and the reference to the Big Lebowski. You're welcome. Thanks for having me, Abram. All right, thank you very much.