 I work as a backend developer in a startup here in Singapore. So this presentation is going to be a little bit less technical, and I would like you guys to participate in it, to make me as many questions as you can. This is a concept I have been trying myself, and yes, I just named it deprecating APIs. Pretty much what it means is, you know, when we have an API and we have this API exposed to the public, we need to. If we are adding different features, or if we are fixing bugs or whatever, we used to create versions of our APIs, right? So in any given time, we have like 10 versions. So your API will be like, let's say you have a e-commerce. So the e-commerce, you expose an endpoint to list the products. So you are going to start with version one, and in any given point, you will have like version 10 list. So that is how you expose your products or your data set. So I personally don't like this approach because this brings so many troubles for consumers. Not for us. For us, it's going to be easier because we just create a different endpoint, different controller, and we are good to go, and we close the shop, right? So this is pretty much what I'm going to be talking about. You don't expect to see too much code just a little bit. Just a few concepts because this matter is really huge. So let's see how it goes, okay? So what the precarity means, right? As I said, it's like, I call it like, we need to, if we pick back to our e-commerce, let's see that we have a list, we have an endpoint where we are exposing our products. So you will have like, let's see, Gustavo.com slash products, right? So but you need this endpoint to be used by your consumers because you are exposing your API, your consumers have Fakih and all the dancing that we need to do for them to use our API. So the first thing you can do if you have worked with services like S-Tribe, you will see like, okay, version one slash products. So the problem begins is what I call the precarity is like, we should keep, if we are offering an endpoint, like listing endpoints, we should abide to this contract forever. We shouldn't create another endpoint called version two, version three, version four. We should keep the endpoint called Gustavo.com slash list and we are the ones who need to take care of this for our customers, right? We need, it's like creating an interface for a given object. This interface is the contract for your object. So you need, if you are exposing an endpoint and this endpoint is a public endpoint, it should be a contract that you are offering to your consumers for them to use your API. So they are not gonna be like yelling at you like when they are just developing something and they say, this is not a function, okay? So this is pretty much what I call the precarity. So the another question that may rise is how I add new abilities to my contract, right? So if we have the control of the endpoint, of course we have the control of the payload. So there is nothing that will stop us to adding information to this payload or removing information. How we remove this information? Please don't do it, okay, I remove the prices payload from my listing because I am not gonna use it anymore because we are gonna make somebody mad, right? So you will deprecate this dataset and these people can see, okay, this dataset is being deprecated, so we know what to do. So that is how we remove data and how we apply new changes to our APIs. And of course, as I said, we don't need to be worrying about prefixing our APIs, creating new controllers, creating new endpoints, creating new routes because we are creating a contract with our consumers and our code base, right? So when to deprecate, right? This is it, right? Let's say that you are working in a legacy code for any given application. So let's say you are running a forum, right? So the forum is, I mean, it was created with, I don't know, with a lot of it. And you are using eloquent and this thing out of nowhere, it will destroy your code base for so many reasons that I don't want to get into it. So now you need to change how you connect to your database, right? So you need to make an improvement in this code base. So that is when you decide to deprecate something. But what you are deprecating? You are deprecating what is this under the hood. As I said, your contract, your interface needs to be the same, which is our listing endpoint. So the API doesn't support importance use cases. Like, I mean, it can be any kind of new cases, right? Let's say that you have an e-commerce and you are offering these products, these products are offering pictures. But now I want my consumers to know my listing price. What are the prices for them? So they can know, okay, I'm consuming this API. These are my B2B prices. But I know what is my margin. So I need to provide this data set now in my payload. So then we decide, okay, we need to deprecate this part of code and add something else. Of course, the API is inefficient. We see if we are caching too much our code, if we are prefixing so many things. There are so many things that can go wrong. For example, I had this use case last week when we were caching our information. But of course, we were caching the whole Eloquent models. So if we had like a thousand listings or a thousand records plus, and you bring that everything with your relationships. And out of nowhere, you have one million records per request. If you have 3,000 requests per minute, that is a lot of data that you need to put in your cache. So that is when you see, okay, I need to fix this. Or the code word you are working on is exposed as really bad practices. As I said, like bad practices can be anything. If, I mean, if I'm not injecting my dependencies, how they are supposed to be injecting our classes, I need to take care of them. And I need to change, deprecate my methods, but I need to keep my contract. My consumers, my customers don't need to know what is the problem in my code days. That is the aim of this. Why don't we create a new version? So that is the question. That is the beauty of it. When we create a new version, we start with version number one. We expose an endpoint, and this endpoint is linked to any given controller. And I have all my crap there. Whatever I want to put in the controller, there. Just put it there. So what happened is that now all your business logic, all your information, all your code is just messed up and is in the same place. So that is why what we usually do in this case, if you need to deliver like by next week and you need to deliver a new version on your API, just create another endpoint, create another controller, copy and paste. Then you have your code, you have your version two of the API, but you are just getting attacked there, right? So that is why I don't encourage just creating another endpoint, because if we have a different endpoint that this different endpoint offers a different information or the API is just shifted, it's not backward capabilities. When I say the API, our internal API, let's say if we are working again with this endpoint, it's listing. So you need to think about, okay, I need to expose an API to my controllers. But this API needs to be something that you just wrap it in a business logic model and you have it like a package, for example. And this is the API, but this API is different from the one that you were using in version one. Therefore, you have a different code here. Now you have a different code here, version two, version one. When you just think about what will happen when you need to expose the version three, how you are going to maintain this. You will have already customers using your version one, right? So that's why I don't suggest doing this. Your consumers need to be aware of the breaking changes. As I said, let's say that you shift from version one to version two and out of nowhere, now let's say you are saving orders for this e-commerce where you're supposed to send the reference code. And this reference code was supposed to be the link between your orders and my orders. So we can keep the track and we can do the conciliation together. I just decided to remove it from the version two. Now when people just go from version one to version two, this code is not there. Why? Because we don't abide to our contracts. So we need to have a contract to abide to. Your code base has grown to support these versions. This is what I was saying. Of course we are developers. We are good. We are just ready to chip code to the cloud. We are ready to do whatever it takes to make some money. We are going to create another controller yet and we are going to create more code. And out of nowhere you have so much code that you don't even know how to touch it. Right? And then it's not about touching code. We are good at touching code. The problem is when you shift your API from version one to version two, there are people who are depending on you, depending on your code, and they are relying on you in order for them to keep their business open. So that is when you realize that you need to take care of these contracts, right? And your tech depth is bigger every day. As I said before, you are just creating files, files, files, files, and then out of nowhere you have something that you don't even know how to control it. So how can we go about deprecating our code to abide by our API contracts? So first of all, it's detaching our business logic from our controllers. So I gave a talk here. I think it was the first talk. So the controllers are supposed to do two things. They don't need to do anything else. They don't need to know anything about our business. They take a request and they dispatch a response. That is the controller purpose. They don't need to do anything. So we need to detach whatever business logic we have in our controllers from there in order for us to keep a clean controller that this controller just know about contract. So therefore, this endpoint is always the same. So that's going to be the first thing to do. We should inject interfacial sampler to take care of this for us, right? So if we deep down a little bit in code, we know that we can have, we're exposing again our listing products, product list in our API. So your AGLIS are supposed to have a listing repository. So you will inject this repo. But you are not going to inject the implementation. You will inject the interface. So in any given chance, you can swap this out. The controller doesn't know. The endpoint doesn't know. And nobody knows. You are the one who knows. Yes, so this is what I was saying. And because they don't know, because these interfaces, they are just interfaces between our external war and us. And all the heavy logic is under the hood. We are the ones who need to take care of it. And of course, because we are good developers, we will have a full text cover to tell us you messed up. So this is a little example here. As I was saying, we have a small product controller. We are injecting our repo. This repo doesn't know what it does. It knows that it's a repo that we are taking there. And this repo exposes a create method. So if we need to create information, let's say that we are working with the REST API. So we are going to send a post request to this list endpoint. And then the request will have all the data in it. And the repo here is the one who will handle the request. There is no validation. You can have your request validation here, but we are not talking about this. So we can do any type of validation. Then we can send this information sanitized to our repos. And the repo is the one who is on charge of persisting this data. Then the repo will give me some information. And this is the info that I'm going to dispatch to make it out of my controller. As I said, controllers just take requests and dispatch responses. They are not supposed to do anything else. So how to deprecate my business code service, right? So I have been playing with this for quite a bit of time right now. So as I said, I always try to write code to an interface. I don't write to an implementation. I have an interface. Of course, the time will tell you when you have to create these interfaces. So you create these interfaces. Then in your implementation is when you change this code. So the way how I do it is I use this deprecated annotation from PHP. If you are using a code editor like PHP Store, it will tell you when this code has bitmarked as deprecated. Then I said, okay, see this method, right? So use this method instead of this one. But we need to keep this method open. We need to have that there because this method is being used in our endpoints. So how we keep this method there? We deprecate the method inside the method. We call our new implementation. So we need to have, of course, a release cycle when we know what we are deploying and what it needs to be care of, right? So after you change all your routes, after everything is good, after your feature tests are passing, your continuous integration is green. You are ready to go. You can remove any test, right? But of course, for this, you need to have full cover. Otherwise, you are pretty much lost and you are just on your luck, right? Okay, so when I deprecate methods, what I do is just I deprecate the methods. I gave a little bit of sugar there. I say, okay, this method has been deprecated for something, right? So my process, I had to do a change in our code base. It's like we have different payment gateways, right? But our bookings, they are related to any given payment gateway transaction. But when we started, we were small. So any payment gateway we were using, they were just providing one transaction. Now we are working with so many payment gateways that now these payment gateways have different transaction per transaction, right? So it has one to many transactions. So there was a change that needed to be there. So we deprecated the old method. This old method was related to the previous method, the new method, and that's it. Everything was covered. And then after everything is shifted, you can just remove your code, right? All right, this ensure developer... Yes, so, yes. So as I said in the end, it's just, it will tell you how you will change your code, right? So it's part of documentation. This is an interface example. We have this product repository interface. So in this case, it's just exposing one method called create. It takes an array of data. And that's it. You need to have this... Whatever implementation you have for this interface need to abide to this method. So that is the purpose of the interface. So as this thing goes here, we have our endpoint. And if we have an endpoint that is just serving any type of data to our consumers, we need to protect that endpoint. And that endpoint is our contract. So it's our duty to keep this as consistent as possible. So we have a repo example here. We implement the interface. We have a persistent interface that we don't need to care about what it does. But we know that our repo is taking a persistent layer. And the create method is just relying to the persistent layer, right? So if you see here, we had an old method that used to save our data. It was named as saved. So we decided that this method is no longer valid because we messed up. So we decided to create a new one. So we deprecate this method, we see create, and that's it. So the important part is like here, we are just abiding to create a method. So we have a contractor in our controller. Yes. So the reason for me for the rest API endpoints is that you will be able to say as a protocol slash save. So now you need to create a save endpoint. You create a new endpoint call slash create. Am I quite the same? No, it's like for example, I will have my endpoint saved, but I will deprecate my code inside. The endpoint, it will take the same post request, but I will deprecate my code inside. So there are two different things. The controller is our code base. But the route is pointing to this store method. This is the store method in the controller. That is the one that is serving this route, and that is the one that needs to be always the same. But whatever is inside that route is what I'm going to dispatch to. So that's the handler. So what happens is say for example, normally this method will return JSON or some data. So for example, I say it used to return last name key. And then now you don't return last name key anymore. So how will you handle this? That is one you need to deprecate the payloads to. You need to add annotation to your payloads and let your customers know that this payload is going to be deprecating in some time period. It's just dictated by the company itself. But it's just keeping everything. Now let's see that your endpoint is changing so much. It's something that is just, okay, this endpoint needs to die because it's not doing what we need. So we create a new endpoint. We can redirect of course the traffic from this one to the northern point. But in matter it's like our main contract is still the same. So of course you can deprecate whatever endpoints with your consumers, but everything can be done. But it's not like we are just creating some version and version of the API. Isn't that a counter argument to the multiple versions? Because let me tell you why. If you create a V1 which has an interface and a payload, and then later when you change the payload or you change the interface, you make a V2. And the V1 endpoint is still pointing to the legacy code which is supporting the old interface and payloads. That means that you don't have to deprecate. You can support V1 for maybe unlimited time and move your code base on V2 to the newer interface or payload. But if you go the way that you're suggesting, which is not creating multiple versions and deprecating, now you've forced your customers to do an upgrade. They have to go to the new version. Yes, that is an argument to be made there. Of course there is a lot of room to be improved there. But the thing is like if you have, let's see, the main example I have with versioning is Stripe. They have 00.1 for years. But what we need to understand here is like if you establish a contract from the beginning with your consumer, and you will tell your consumer how your API works, we do work here. So we can deprecate this method. Now this is in PHP. If you have this code running in Java, which is where I took this idea from, when you deprecate this method, Java is just doing an end routing, and it just goes to a different method, a different controller, and it dispatches the payload. But the problem there is the payload. Yes, this is what we are concerning about. This is our concern. And yes, if we are, we yet are going to remove payload or our payload, so that is something to be made there. Do we want to do that? For example, something that I have seen in my experience is when you create different versions of your API, you have to support different versions of your API. Of course, if you have a big one, and if you have a customer that is using your big one after 10 years, if you don't shut down this API, this customer is not going to move. So I have seen this myself. So if you somehow create a contract between you and your consumers until you are going to use my API, it's not like I'm going to deprecate this code, and next week it's going to be shut down. We have to have an app. So for example, some things that I have seen of Google doing is, okay, we're going to deprecate whatever API in one year. So then you have one year to do it. Is it up to you to do it or not? Now, if there is an argument there to be made, it's like, do we want to do that? Do we want our customers to leave or to stay? So yes. So that is the war between APIs. Definitely a war. The one part that I kind of feel like there's a hybrid between your two purges, actually. So for example, one thing that one of our vendors does, which I think is really smart, is they have a v1.x. Okay? And so the v1.0, where you start with this contract, you've got an interface and you've got a payload. When they go to 1.1, the payload changes, but the important things are still in the v1.1. So they still use it. It's got extra stuff you may never look at, but it still is the same. And as long as the core parts of the payload stay the same, it becomes 1.1, 1.2, 1.10, 1.11. Only when the core changes does it... Yeah, it's our duty to keep our payload consistent. So that is like, for example, what I was explaining here is how we can keep it in our end. But of course, this is a valid question, like what is going to happen if we want to remove a key, which is going to happen. But for example, the longest I had worked with an API was for like 10 years. And for 10 years, we didn't remove a single key for the payload. It works, why break it? Yeah. So the thing is, yes, that is a valid question there too. Now, versioning, the way how Stripe do it, which is amazing, they have, if you are going to use their SDK and you want to use, let's say you want to use the version B1 when you are instantiating the charge object, which is the one that you use to charge the credit cards, you can tell them what API you want to use. I'm pretty sure that under the hood, do the same because it's really difficult to maintain this big base code. So that's pretty much the argument to be made there. Yes, I miss the part of keeping our payloads consistent. Yes, that's a good point. Because what we don't want to do is just breaking code. So I'm versioning, break codes, and of course, payloads, break out. But yes, for example, we had an API, it was version one. We have two versions right now of our current API. So we have so many customers that they don't want to shift to the version two just because it's working for them. But we don't want to support this API anymore because we have been supporting this API for more than five years. So we need to change this code. But there is no way for us to change this code if they don't shift. So then if, how you are going to deprecate this code because they are not code-based, the code base just shifted. So there are two code bases that grow up out of nowhere. Yeah, I wish. So any other questions? Thank you for the question guys. It was really nice. No questions? Thank you. Thank you. And presenters have flushes. Thank you. This is your second one, right? Yes. There is no limit. If you talk ten times, you will have ten flushes. Even a serial of the black market is up to you as well.