MVB: How to build the backend for a Two-sided marketplace

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey there my name is prakash and i am one of the co-founders in the head of product of zano uh on the line with me is mr sean montgomery he is our ceo and he's also going to be running through this new series that we've put together we're calling this the minimum viable back end we've heard from a lot of our customers that they don't necessarily know how to get started so we thought we would put together a couple of quick tutorials on how to build very popular types of applications for this one specifically we're going to start by talking about the two-sided marketplace and so we'll cover how it's built how to get things set up and how to get going before that if you are joining us for the first time and you have no idea what zano is uh zano basically is the fastest way to build a no limits back end for your application so uh if you're a beginner we have the front end that's what the user interacts with and then on the back end we have things like the database and the api and all of the business logic and a scalable server zano provides all of this so you if you don't know zano and you're building your next application definitely check it out so let's go ahead and get started first of all what is a two-sided marketplace and um i took this image off the internet that basically describes it pretty well there's basically two sides uh when you think about a two-sided marketplace and you can think of apps like uber or something like ebay there's a demand side right these are in the uber's case uh customers that are needing rides and then you have supply side and the supply side is things like drivers and so when you're building this type of application you need to kind of think about structuring things in a way that's going to accommodate the relationship between both of those sides so some examples of two-sided marketplaces uh popular ones at least there's airbnb uber wag which is like dog walking for uber ebay etsy etc so uh if you're starting to think about building a two-sided marketplace this formula has already been created and you can leverage a lot of what we're going to show you today to build your own so some things that we're going to cover today we're going to cover some basic database schema and setup so we're going to talk about how you set up the demand side right those customers that are needing that ride and then we're going to talk about the supply side and we're actually going to do an uber type example today so we'll also be covering tracking uh that demand side or that driver's location and then basic reservation how do you link the two relationships together things that we're not going to get to uh today but are equal that are pretty important are any third-party integration so think about how you pay your drivers or you take payments that's typically done in stripe messaging how you communicate with your customers and that's done typically through something like sendgrid or twilio recaptcha for security and then finally chat or real-time location which is handled uh via ably or websocket technology so for these things you can always message us in support and we can help you kind of step by step we also offer office hours and orientation to go through these more complicated dynamics but still getting started with the basics is gonna help you get a good head start on how to build a two-sided marketplace for yourself so with all of that said i'm gonna hand it over to our ceo sean uh to take it away and to start building this and i will comment if he misses anything to get started all right so sean go ahead awesome let's do this all right i'm gonna share my screen okay so first we're going to create our project so i'm just calling this marketplace inside the marketplace so i'm going to have both the drivers and the customers uh have those be the same uh objects so they'll both be referenced under user we then have trip so trips are just instances of the actual rides we also have let's say vehicle and then [Music] potentially transaction so i think this is a good start so let's uh go ahead and so now that we've got this database set up uh let's uh make the [Music] the distinction between customer and driver so here uh we can probably just have a list of roles so here we'll do a list so we'll say roles and then this could be driver so this could also be administrator okay so let's have two users we'll start out with sean and we'll do prakash i'll go in here and make it so that shawn is a driver and prakash will just be a customer so the absence of a role means that you're a customer okay so the next thing is vehicle all right so let's say we have a title we have a license and then we have a reference to the user which should be a driver so here we can say we've got a mazda oops let's say mazda3 the license plate is just making something up wrx123 this will be linked to sean who is the driver okay so then the next thing we also need i forgot we need um a location which is just a latitude longitude okay awesome so we could just say there we go okay so then um i just realized we also want a location on the user so technically there's a chance maybe there's a chance maybe we um so location on the user seems like that makes sense for the customer however for the driver it probably makes sense to keep that on on the car so there may be some redundancy here but we'll come back to that and and that's because as as the customer the driver needs to know where i am right um and then the driver this is the you you want to keep it over on the vehicle because that's where the vehicle is at the time and you're going to do the uh the mapping that way is that correct yeah exactly okay okay so then the next thing is what indicates a trip so the first would be customer let's rename that so it's super clear and then uh also with a vehicle and then we automatically get the driver through the vehicle so then um we could have a state and oops there we go so we um let's say started or uh sean is building this out typically whenever you have a relationship between two different user types you have some sort of ledger and what this trip database table really is is just a ledger that keeps track of the relationship between one user in this case the customer and then the other which is the driver so that is kind of why sean has this separate table um flushed out to do this yes so um we also want to know where so we have a start and we also want to have a stop okay so we've got the users we've got the vehicles we've got the trips um transaction probably seems like it links to the trip let's just add this so maybe we say that this is a price and then we have a trip okay all right so i think this is enough to so we can start fleshing out uh the api so let's go to the api we'll do a brand new group so we'll say marketplace [Music] okay so the first um the first endpoint is probably what dr what cars are near me so what cars are near me or what vehicles and just again as sean is fleshing this out just keep in mind this is an api endpoint that would be called from your front end so imagine that a user is looking at their app and they're looking at a map or a list of drivers that are near their specific location so this is the api endpoint that sean is flushing out right now so we have vehicle location and then we want to do some of the geo features here so within the n meters let's do a thousand meters actually we want um we probably want a couple miles so let me do a quick calculation here so five miles in meters there you go it seems reasonable and then it is equal to true okay and just before you move forward sean let me just kind of summarize what happened so sean added an input and that is what uh value is being passed from the front end so this input can be something in meters right and then he added one the first function in the function stack this is kind of where all the power of zano lives and that is to query all records from the vehicle table and uh he made a logical filter within that uh that query the database query that says hey make sure that it's within five miles whatever the user inputs make sure that it's within five miles of that location so that's kind of like high level explanation of what he did and now he'll move forward from there yeah so um i just went and copied so i randomly picked a spot somewhere in los angeles that's where the car is i then went and copied that so technically i'm doing the exact same uh latitude longitude which means it'll be a zero distance so this should return one clone perfect okay so then we can then tweak this so if we change one of uh the digits to the left of uh the decimal that's probably a very large distance so this probably does not return anything perfect okay but if you can if you just do it and and just i and for people like i think you can get the latitude and longitude by going to google maps right if you went uh for example like arizona it would and you pick a point it would show you the latitude and longitude that you could then enter here to test yourself yeah exactly okay so here now we have cars near me however we probably now want to know whether or not what is their state so we want or actually we want available busy i guess we i guess they're just two states available or busy yeah that sounds good and we'll default to busy okay now sean just a quick question why on the user table did you do a list of enums and on this one you did just a single enum on the user table i wanted to have it so that you could do multiple roles so potentially you could be a driver but also administrator uh technically that's me um it just allows you to have uh and as you add more roles um it's just nice knowing that you can just keep adding more and more regardless of how many there are okay that's helpful okay so now we want what the vehicles are near me but also available so state is equal to available okay so that should still return something perfect all right so then the next thing is to book that sounds like what we want okay so now we have book vehicle set that to authenticated um so we want the vehicle all right so now we're going to get the vehicle based on the id and then we want to do a precondition make sure it is present so a precondition for those of you that don't know is basically a function that evaluates a statement and returns true or false so when you basically see errors that return to you on the front end it's typically being triggered by a precondition that's basically evaluating something and then returning an error message so that is exactly what sean's doing right now okay so this is saying i want to make sure that we have a vehicle and it is available um so let's do my auth token i am doing vehicle one okay awesome and then vehicle two doesn't exist should throw an error perfect okay and then if i so let's go back to one and and one more thing here before or yeah so one thing you'll notice about that api endpoint is he made it authenticated so this basically means that a user has to be logged in in order to execute this now zano makes it easy you'll see on the right hand side where you can automatically authenticate with a user in your system by in the run and debugger so that's what sean is doing here but otherwise if you were doing this in your app the user would have to log in put in their password in order for them to execute this final question kind of regarding this sean in uh function stack item number two you do vehicle one uh does not equal no can you just talk at a high level about what why you're evaluating this null statement yeah so sometimes people can enter in an id um accidentally or maybe even the the application has a bug in it and it's referencing the wrong id so that would mean it returns uh it may be referencing a vehicle that doesn't exist so this is just making sure that this id should turn into a vehicle that actually exists in the system otherwise we may like down the line maybe on like step four or five we could get a weird error because we're trying to reference like vehicle dot id and that doesn't exist because vehicle is null right and another piece of this is on the precondition it said precondition failed but you could have also put in a custom message right if you wanted to yeah absolutely so we could say this vehicle does not exist [Music] there you go yep so that that is the error for example that you would pass to your users on the front end you might say uh you know you really would say anything that you want there but this allows you the flexibility again to evaluate a statement and then pass back an error yeah so now i'll make the vehicle busy um and bring back to one so now i should say this vehicle is not available yeah so there's two there's two statements that are evaluated there okay so the next thing is so now we have a vehicle that's available um and now we want to actually create a trip and so as sean is doing this you'll you'll notice that he uses run and debug a lot and he goes back and forth to the database and this is what's going to happen with you as well as you're creating your application you don't basically build out your entire function stack and execute it immediately you want to basically go step by step and use the run and debug tool to make sure that things are working as you move forward so that's kind of what sean is doing as he starts to build this out okay so we need a start and a stop actually the um no that makes sense we want to start in this stop so this would be the trip origin and the trip end right the destination right so we then map this start and stop so what he's doing here is he's using the function add record it's one of our database functions in xeno and then he's filling out all of the different inputs and so he's taking the start and the stop from the user input and he's making sure that that gets populated uh in the trip table once this is executed okay so what we're doing here we're getting the vehicle making sure it's in the right state we're then adding a trip uh which is referencing the vehicle and the start and stop and then we're also updating the vehicle to be busy all right so let's go back here just so i can get that uh point so we will do to make things easy we'll just do a trip with the same start and stop oops there we go okay so vehicle one that's the mazda we've got our stop and we have our stock uh start and stop all right so let's do run and debug okay so what this means so that returned the vehicle there's other stuff going on here like the trip uh but if we come back here so vehicle if i click on this the state should be changed to busy perfect that's good we should have a trip entry so we're saying sean well i authenticated as myself i should have been done progress actually let's do this again so we'll go back to vehicle we'll set it to available and this time i'll authenticate with prakash there we go okay and i can use the same points we'll come back here now the trip should be prakash book the mazda3 it just got requested and it's got the start and stop so i think that is the first step so now we need the next api is so now that it's been booked is to say that the trip has started start trip okay so this would be a reference to the trip id we're going to get the trip we're then going to once the trip we want to do a precondition so we'll just make sure that that exists and just as he's writing out this precondition you're going to notice on the api endpoint for um for booking the trip and also for starting the trip he's using a post which basically it tells the api that we're basically writing to this api endpoint on the get available cars he used the get so that's typically uh what you use to just get information that doesn't mean that you can't execute um uh things that write to the database in a get command but typically best practices this is how you would do it okay so we have trip one precondition failed oh that's because it's trip two that's why all right so that was a good example of the precondition actually doing the right thing okay awesome so we have a trip that's requested but now i need to do something with it so then so once we get uh the trip we also can make our lives easier let's say i want a vehicle on that so sean is using what's called an add-on right now and then add-on similar to graphql enriches the response that you get in the same request so you see like he's added on the details of the vehicle in that same request so it's a very easy way to basically enrich the data that you are getting back yeah so and then we can add another precondition because i can only start the trip if i happen to be the driver so here i would want to see trip dot vehicle dot user id i think that's right it's equal to the authenticated id let's see if that's right i might have a typo oh that's what i do yeah so this is shawn now using the debugger uh when you run in debug there's a debug tab that allows you to basically go through how this query was executed and find out where it might be failing which tends to happen a lot when you're building these unique endpoints and sean is doing definitely best practice around adding all of these preconditions to check that all of the states are uh are nominal before he actually executes this trip yeah so here i just did i picked myself so that's supposed to work if i picked for tosh who is the customer it should not work so get the precondition so that just makes sure that only the driver of that vehicle is running this api and otherwise it throws an error okay so the next thing is uh now we need so only the driver can start the trip is what you're saying so now we're going to update the trip with the new state um i'm gonna go with started um i think we can skip confirm i mean technically you can keep adding more states like hey i'm on my way um but since we're kind of like on a little bit of a crunch we'll just go to start um okay so let's actually start this trip okay let's go back to the database this trip should now have a different state started awesome [Music] and then the next thing is so start and then stop so we can actually make this real easy because we can just clone it okay so it would be the same almost the same thing instead of requested it started all right and then instead of edit editing started it is complete actually we'll rename that to complete trip okay awesome so the next thing um actually i just realized there's one other thing so once the trip is complete the vehicle needs to go back into available so we will update we've got um what is it trip one dot vehicle and then we want to set available okay awesome so let's actually complete the trip and again i'm going to do prakash here so that should throw an error okay i'm going to switch it over to sean and this should work did not work let's see what happened um oh i did the same mistake with the wrong trip id there we go trip two okay awesome so we're gonna check two things first we go on the trip and the state should be complete now perfect all right then we go to the vehicle and it should be available awesome okay so i think there are there's one more thing that would be nice to have and it would be um bless you let's do let's do um two things we'll do my customer my trips i guess yeah my customer trips and my vehicle trips so depending on the driver or customer so we'll do my customer trips all right we'll do query all records trip and then oops we want to do a custom query so customer is equal to authenticated id so this is a customer that has logged in and wants to see all of their trips right yes okay oh oh it's probably because i have the wrong so prakash yeah i'm the customer there you go awesome okay i have one trip uh and then we can do the add-on again and since it's we already created it should be right there so it's super quick we'll rerun it okay awesome so then we can do we can clone this to be my vehicle or driver trips and then what we need to do is change instead of customer id okay so actually this gets a tiny bit trickier because the the driver id is available through the vehicle so we have to do a join so we'll do via trip dot vehicle id is equal to vehicle id basically just mapping ids so just just before we move forward because i know this is going to trip some people up talk a little bit about high level the inner join and why you needed to do it in order to get the driver yeah so um what we're trying to do here is show a lit just unlike the just how you saw on the previous screen where it was a list of the trips that the customer took that was really easy because the customer id was right there right but to then do the uh the alternative perspective where it's i want to see trips that the driver took the driver id is not there but it is available in through the vehicle so we basically need to group or sorry we need to join those two tables technically like putting them right next to each other so that we could get access to this user id right that's all it is so if you don't if you don't immediately have uh it accessible um you make it accessible by bringing in the other table so you can reference it so and i just realized i forgot i forgot to hit save on that one yeah so just just as as you're recreating this again as sean was mentioning a vehicle belongs to a driver but it may not necessarily be immediately available based on the type of api you're running so you make it available through an inner join and that's kind of what sean is doing here in this exactly all right so now that we so first we do the join then we make it so that the appropriate vehicle lines up so we're doing the i want the vehicle database table lined up to the trip uh based on the vehicle vehicle id uh if we didn't do that it would then be out of order and you may have someone else's car so let's just make sure that the right car is there for the right trip so now that we have we've done that we then can now update this instead of customer id we can reference vehicle id is equal to auth id and that shows up because of the join as soon as you join something it's accessible to you in your little input selector and then you can do the query just like shawn did yeah okay so now we'll do run and debug um we'll do the driver yeah we'll do prakash on purpose so this should return nothing and then we'll do because he's the customer if we do sean then we should get the list there we go awesome so yeah that's kind of the gist i mean we're definitely over simplifying it there's still um a lot of things can go wrong uh driving a car and there can be issues so there's still more robust stuff to handle or to flush out when things don't go perfectly but uh at the end of the day um it's really just kind of adding a couple more endpoints here and then we would be integrating uh the third parties to make sure that like right now i just booked a a trip technically it was for free right uh we want to actually charge um so that would be that'd be a separate thing yeah this was great and so uh just a couple high-level questions here if you go to your database why did you decide to have just a single user table that encompass the demand side in the supply side rather than separating out as two different tables yeah good question so the nice thing about this is technically a driver could be a customer right that actually just because you're an uber driver doesn't mean you're forbidden from ever enjoying the perks of having someone else drive you around so by having the same user table it allows you to take on different roles and that's why we have that uh that rolls uh the list of rolls so if you did keep it separate um it's it still is technically possible that you can make it so you could be uh you could play both side but you'd have to duplicate date duplicate the data uh which kind of gets annoying anytime you duplicate data you then run the risk of having it get out of sync and really you kind of just want to avoid all these unnecessary complications and it just makes things a whole lot nicer just having one single table for anyone who's accessing the site regardless of perspective yes and how about i notice that you have four distinct tables here do you have a method or a way you think about which objects should be their own separate tables versus properties within an existing table yeah so um i'm also realizing yeah we didn't really use transaction transaction really would come in uh handy when we really did because right now technically all the trips are free it's a little bit of overkill but when we do start linking in stripe um and also realizing that uh payments technically just as trips can go wrong payments can also go wrong so you kind of got to manage state uh when potentially maybe something charged and then there was a chargeback like handling all those different cases so i know this really wasn't used today but when we really link in the stripe support uh that would be more important there but in terms of when why use uh different tables versus referencing them so well a good example is the roles right technically i could have created a roles table and which would just have been a single role so right now we have a role a list of roles so if you had another table would be a single role and then a reference to the user we could have done that that's definitely way heavier like i think everyone can agree updating a role by clicking and going in there i mean that's pretty nice right it's uh you have all your data localized like i know i'm looking at prakasha's record right here it's very easy to tell whereas if it was another table you kind of lose that for this specific view you would then need to i mean your whatever your administration panel is would have to make it so that uh you could tell what records were related to another so sometimes it's easier to just keep things it's called having the data localized so so it's just convenient um having the data right there does that apply to everything no no it does not so basically anytime there's it's a small amount like we're not having a thousand rolls for prakash like it might be like currently it's possible to have two at the most right so that's a perfect candidate for having just the array as part of the table if this was uh bigger like for example the trips like what happens if i do a trip every day so after a year we've got 365 trips uh and after 10 years 3 000 plus trips right so that definitely feels way too big to be put in an array even though it'd be easy to edit it it would kind of you would kind of outgrow it just because there's just too too much data so that's a perfect example of why you would want the trip in a separate table and also one thing one more thing to keep in mind anytime you make an update here it's updating the entire row so if we had let's say that that 10-year example if we had 10 years of trips all in that row and i wanted to make a new trip it means we'd be re-saving all 3 000 plus trips just to add another trip right and that obviously seems uh like overkill uh so yeah again really there's kind of like this gauge of how many records are or how many records are there going to be in the roles case it's maximum two in the trips case it could be thousands and then how often is it going to be updating and uh like roles don't change that much you once you're a driver you're pretty much a driver right um yeah so hopefully that made sense yeah definitely makes sense and this kind of gets into the power of zano allowing you to do relational and non-relational type layouts and views uh as sean is mentioning if you want if you have a large data set like the trips table and you're going to get into thousands of rows cno allows you to create a separate table and then just do a simple table reference but if you want um data localized just like this like roles is maybe never going to get more than five then you would do that here and i've heard a good rule of thumb is once you start approaching you know like around 100 things in your list like in your roles table that's when you were going to want to start thinking about separating it out into another another table altogether so um this was a a really great overview once again sean if you could just go over to the api we'll just talk kind of at a high level just wrapping it up about the different endpoints that were created so um first and foremost you kind of have the the top two that we're seeing the ability to book the uh vehicle and uh complete the trip so click on book the vehicle very very quickly so as you can see it took three inputs from the user um first of all which vehicle was being used the beginning of where the user was the origin and then finally the destination and then at the function stack this again is the power of where xana really excels it it can do multiple things can um go through multiple preconditions to really make sure the environment is right to execute it so in this case it gets the record based on what the user has entered and make sure that the vehicle actually number one exists and it's available and if all of those things pass then it's going to start the trip right and it's going to change the vehicle state to uh it's being occupied so you can see um anytime you're building an application your application is unique it has these nuances and the function stack allows you to kind of define all of those things and so sean created a number of different endpoints i encourage you to to watch it back again uh sean one more thing go back to the database table um here uh or just go to back to the database we use the example of uber but this would apply for another two-sided marketplace so for example if you were doing something like um an airbnb you know uh your user might be uh your it'd be a combination of your hosts and also your guests that would be the user table and the different roles might be a guest versus a host that's what you would define there and then instead of a vehicle it would be a place to stay or a location where you would stay so you can see how this maps to these different two-sided marketplace concepts sean just kind of showed you how they all linked together um as i mentioned we're not going to go over the third-party integrations because uh it would just basically go over time there's just too much to cover there but again we offer uh weekly office hours twice a week where we're happy to help you build so we we hope that you find this helpful or you found this helpful and uh please just let us know in the comments below whether you have any questions any clarifications or any future type of mvb uh videos that you would like to see us do so thank you so much for your time and we'll see you on the next one thanks guys
Info
Channel: Xano
Views: 6,324
Rating: undefined out of 5
Keywords:
Id: H1JBOJn6LDA
Channel Id: undefined
Length: 44min 37sec (2677 seconds)
Published: Mon Jul 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.