Time Jump Links
- 00:42 Backend knowledge
- 02:05 Databases are so hot right now
- 08:46 Sponsor: Linode
- 09:56 What is the state of just using native web components and are they a viable solution for a production app today without a framework dependency?
- 15:33 TypeScript conversations
MANTRA: Just Build Websites!
Dave Rupert: Hey there, Shop-o-maniacs. You're listening to another episode of the ShopTalk Show, a podcast all about front-end Web design and development. I'm Dave Rupert and with me is Chris Coyier.
Chris Coyier: Hey, dude!
Dave: Hey, Chris. How are you doing?
Chris: I'm doing pretty good.
Dave: You know I say front-end every stinking week, but you and I have been kind of elbow-deep in the old back-end lately, so--
Dave: Maybe we need to change the mantra, the intro to--
Chris: Yeah. I'm also -- but I actually know about front-end development and I actually don't know anything about back-end development. You do.
I don't want to say nothing because I've been around the Web a long time and I end up touching that code, and now I'm making a concerted effort to try to really put on that hat, and I'm enjoying it. Yeah, we can talk about it, but I definitely have to put a big asterisk by the things I say about back-end stuff because I don't have a lifetime of experience to draw from there.
Dave: No, and you know it's funny. In the D-d-d-d-discord, people are like, "Do you know of a back-end podcast? [Laughter] There's full-stack. I'm not going to name names because we're kind of in competition with them, but--
Dave: But I think I listen to the Change Log, and that was kind of full-stack. It kind of had some Rails beginnings and stuff, and so I'm trying -- but I was trying to, like, man, is there really--? Rails Bytes used to be one, too, I'd listen to. But is there a really good just back-end podcast?
Dave: Like how to maximize your Stripe account. [Laughter] I don't know. Is there something like that?
Chris: Yeah. What's new in databases? Um... Yeah.
Dave: Well, databases are hot right now. Can I go on a tangent here?
Chris: Yeah. Sure.
Dave: You've got Supabase. You got PlanetScale. You've got Prisma. You've got -- I was doing some other. There's this thing called Rill. I don't even know what Rill is, but Rill connected to DuckDB, and so you go to get Rill--
Dave: I think it was get Rill, or Rill connects to DuckDB. What's DuckDB? I don't know what DuckDB is, but it makes charts and graphs for you, and that was pretty cool.
We're in kind of, I feel like, a heyday of cool database technologies. Snowflake, Amazon DynamoDB: I don't know this stuff. Somebody does. But there's a lot of cool database tooling out there right now.
Chris: There really is. You're right. There's a lot of that. I wonder if some of it is--
I don't know what the origin of it is, but from a startup perspective, when you have someone's data, the churn is low. And if that was the only thing you cared about as a company is, like, I want to get customers that pay money and don't churn, I'll tell you what.
Chris: Having a data warehouse is a pretty fricken' good idea.
Dave: No. Yeah, I mean data and files and customer identity, which I think I've just described the entire Supabase platform. [Laughter] You know it's -- yeah, I think it's just a very cool world. Database tooling has been kind of bad for a very long time--
Dave: --from the Node world, right? Rails had active record and it was awesome. Then people hated it for some reason because it was too awesome. But the database tooling right now, I feel like, is kind of just getting so good. There's also, not to mention, GraphQL and all this other infrastructure -- Fauna, Hasura, all this stuff.
Dave: There are all these new tools to kind of interface with your data in ways that--
Chris: So hot right now.
Dave: --didn't exist five, ten years ago.
Chris: Here are a couple of other ones. Remember I did my dumb thing about the edge and how data usually isn't at the edge? There's a lot of stuff that's at the edge. Functions more and more. Key-value. All your static files.
Chris: But less and less just your actual data, right?
Chris: That's the thing that's got to go to a single origin server. Yeah, a little bit on that.
There were a bunch of replies to my original blog post to a thing of fly.io, which looks pretty cool because I think you host a bunch of stuff and then you say, "And move it all to this other region, too." It really helps.
Their tagline is "Deploy app servers close to your users," so it doesn't matter what tech you're using. It will pick up your stack and plop it down in a different region for you, so it helps make multi-region stuff good. Maybe not quite the edge, but at least you can do multi-region a lot easier with this, I guess.
Chris: Which is pretty cool.
Chris: Notably, when I wrote that, I was like, "Well, you know, there's always KV," which is Cloudflare's data storage thing that is actually edged out.
Chris: Which I think is really cool. Then what was it? Just last week, two weeks ago, they're like, "Here's a new thing: D1," which is SQL Lite at the edge.
Dave: Whoa! Yeah, yeah.
Chris: So... That's pretty hot, I think.
Dave: Yeah. Yeah. I mean they're steamrolling. And it's all the data stuff. The key value gave way to SQL Lite. You know? We're there.
Dave: It's a good time for data. But that's kind of back to what you were saying. Once you've got somebody's data, you've got them forever as a customer. I agree. But I think that's what gets me on these tools. It's like I don't change my data structure too often. I'm never like, "Oh, gosh! I really need SQL Lite, but I just can't figure it out." You know? [Laughter]
Like, "Oh, I need this one on the Cloudflare. I should use that." You know? I guess my brain isn't like, "Man, I need a one-off database today." Not that often, you know, so I'm curious how that sort of stuff--
Chris: The amount of customers you get is probably lower, I would think. You know? You don't Hello, World a new database that much. If you do, you're like, "Well, that was interesting, but I'm not moving my entire world.
You've got to get them right at that moment where they're really actually building something for production.
Dave: The key-value stuff seems very cool. Who was it? Andrew from the D-d-d-d-discord, he has (on his blog) a little like counter, so you click it and it'll put a heart and it's there. It's persistent, and it's based on you.
Dave: You didn't have to log into his website.
Chris: Pretty cool.
Chris: Good blog post. Probably better than that, but remember we even did -- me and you did a video on that. [Laughter]
Chris: One of our ShopTalk videos was literally using workers in KV to make a little counter blaster. It's fricken' easy. [Laughter] So, there's that.
Dave: No. Well, and it's so -- it was cool to see it. I know we talked about it kind of theoretically, "Hey, here's something you could do," but in a production situation where it's running, and it's not aggressive. It doesn't bog down the page. It's just a fetch call to a little worker that lives somewhere.
Chris: Yeah. Well, there are some caveats. And I hate to easy, like I just did, because that's really relative.
Dave: Yeah. Yeah.
Chris: I'm sure there are people listening to this that probably wouldn't find it so easy, but I mean kind of easy comparative to setting up an SQL database, at least to me. You know?
Dave: Oh, yeah.
Chris: And buying hosting for it and getting that all good, and then building a rest API for it that increments it but does so in an efficient way and is eventually consistent. Then not to mention the edge thing. It's one thing to spin up a MySQL database, but that does not at the edge.
Dave: Mm-hmm. Mm-hmm.
Chris: Which means lots of latency for Australia.
Dave: Well, because he does. He has to get call to get the number of likes, you know. But now it's very fast.
Chris: Sure it. Eventually consistent.
[Banjo music starts]
Chris: This episode of ShopTalk Show is brought to you in part by Linode, linode.com/shoptalkshow, who were voted the top infrastructure and service provider by both G2 and Trust Radius. Accelerate innovation with Linode. Simple, affordable, accessible, Linux cloud solutions and services.
It's a Web host. It's a good one. It's been around a long time. It's very affordable. It has awesome support. They do a great job. This is basically the gist of it.
Build everything yourself or use plenty of Linode one-click apps to deploy everything from Plask to WordPress to Valheim, to Minecraft servers. Pretty rad, right? You don't even have to figure out how to do that. You just boop, "Oh, I have one now. That's great."
Every plan comes with amazing human-powered customer support. If you need help, someone will pick up the phone, respond to your email, or reply to you on social media 24/7/365. That's an amazing promise. That's for all the plans.
Aside from cloud hosting, Linode recently added GPU hosting plans for machine learning and neural net use build with RTX 6000 GPUs.
Thanks, Linode. Y'all do a good job. Thanks for the support.
[Banjo music stops]
Chris: Uh... Let's see. Micah Mills here writes in. "I've been doing front-end dev work for over a decade. I've seen trends come and go. I like the idea of building with components."
Heck yeah, Micah. So do I.
Which I think is fair to say. I think I agree, Micah, the concept of components will outlive any particular framework.
"What's the state of just using native Web components and are they a viable solution for a production Web app today?"
Yeah, we talk about Web components a lot, but [laughter] just, I guess, Micah is wondering if that's a good long-term bet, to which I'll say I think it is.
Dave: Ooh, bold choice. I think so. I mean I'm, of course, going to say yes.
Dave: Subscribe on front-end Masters.
Dave: I think, yes. I think what is maybe missing is a lot of Web components is kind of like this works in a multipage app, like your Rails app or your Java app - or whatever. But you can also kind of do enough to get the shoehorn in a single page app vibe. You know? Kind of more like your React flavor. I think there's maybe not enough tooling or information about how to do that successfully over dozens and dozens and dozens of views and templates.
There's a pretty cool tool from Open Web Components, Open WC, that is like a Create React App for that, so you could kind of whet your appetite with that. But that's, I think, what's missing from the framework. If you're like, "How do I build a Vue app, a single page Vue App?" dozens, thousands of articles.
Dave: How do I build a single page React app? Dozens, thousands of articles. There's a meta-framework called Next that you should use. For Vue, there's a meta-framework, Nuxt. There's no meta-framework for Web components yet, is what I'd say.
Chris: Hmm.... Yeah.
Dave: And so, there's not a true--
Chris: That seems like a good opportunity, doesn't it?
Dave: Definitely, but there's just not tried and true, like, this gets you everything you need out of the box -- I think, right now. That's what I'm going to say. But I do think Web components are part of the platform, and so they have an inherent advantage [laughter] in their longevity.
Chris: Maybe people would say -- maybe if you got started using it or got started writing one of those, you'd be like, "What am I doing? Why don't I just say Svelte is that?" and then use Web components in Svelte because what you want to do is fill gaps.
You're like, "Well, I need a state thing." Oh, they have that. Why would I write one from scratch when these other frameworks do it so well?
Dave: Honestly, Svelte is a pretty good Web component generator because I think you just add Svelte options Web component - or something like that - and it's done.
Dave: I can get the actual code, but let's see -- going to my super-secret guide book for my Front-end Masters course.
Chris: And then you get everything Svelte has, which is a robust set of stuff.
Dave: Oh, no. My page is offline right now. It's Netlify down?
Chris: What?! DaveRupert.com is down? No, not for me.
Dave: No. No, my secret URL for my course book. I'll have to look into that.
Dave: All right. Let's panic. Panic. Okay.
Dave: But guess who is using Web components as an app. Photoshop.
Chris: Oh, yeah.
Dave: So, big companies are using it, so I think you can do it. I think it's totally absolutely possible. I just think the DX, if you want to say, is still probably on the side of these other tools.
Chris: But for long-term, if that's what you're really thinking, you're thinking, "I'm going to write this app, but I don't want to rewrite it next year," because some day React will die. I know that sounds crazy. It's so big. It's going to take a long time, but some day it won't be hot anymore.
Then there'll be this long period where there's still plenty of stuff written in it. But React's adoption compared to jQuery's adoption is nothing. It's nowhere near that.
I know that's complicated because it actually turns out that the higher you get in the most trafficked websites on the Internet, the larger the chunk of React is. But longtail, it's nowhere near. But people don't build new stuff in jQuery these days. It's finished.
Chris: Not because it's bad, because that stuff moved to the browser, and things like that will change in the future, and you won't be rewriting your app because you've written it in a native technology, whereas other people might be considering, "How are we going to un-React-ify this thing?"
Chris: Okay. Okay. You know we were talking about back-end stuff so much. We've also danced around TypeScript on this show because I feel like neither of us have a production TypeScript thing, or do you now?
Dave: No. No, still not there.
Chris: Not really?
Chris: Okay. Okay.
Chris: You know? They'll just be like, "Oh, if you want TypeScript, do this. If you don't, do that. And it's fine. We support either way." All the build tools, all the stuff supports it, and I think that's probably a smart move.
There are some things that you do that don't have a choice. I've been working with Go a lot. I spend every day in it. You don't have a choice. It's a typed language. It's typed, period. That's the deal.
Chris: You know?
I'm not on either side yet. I'm seeing the value of it, but I'm also spending - no joke - most of my team dealing with types.
Dave: Mm-hmm. Yeah.
Chris: It's just funky. You know? [Laughter] I almost made a joke at the top of the show where I'm like, "I should asterisk this thing." An asterisk in Go is a dereferencing appointer, and you use pointers so flipping much in this language.
Chris: Constantly. Your code is full of ampersands, which are, like, "This thing is a pointer to this other thing," and then an asterisk to say, "Okay, I'm dereferencing that thing that is a pointer because I need its actual value now."
Some of that makes sense, like if I call a function with a pointer. I'm changing the thing that I'm pointing to, so I might not even need a return value or something. It can be kind of efficient because memory is shared.
Chris: Whereas if you don't use a pointer, you're passing a copy of that object over. Usually, I'm not thinking about that because Go is so fast and efficient anyway that I'm like, "I don't care about optimizing it." Maybe we should for big-time production stuff, but I'm usually not the guy in charge of that, so I don't care that much.
Usually, what I find, though, is that I'm not writing pointers because I'm worried about efficiency. I'm doing it because what a pointer can be (at least in Go. I'm not sure how it works in TypeScript) it's either this type of nil. So, if you say, "Here's a thing and it's a bool, but it's not a pointer to a bool," it's just a bool, it is either true or false. It cannot not be defined. It has to be true or false, and it will initialize itself as false.
Chris: But in programming, sometimes you need it to be, like, "Oh, well, this started off as a piece of JSON, and it's actually just not there, so it's not defined," or something. Undefined things are a part of programming.
Chris: In my world, a lot, so you would have to make it a pointer to a bool, so that way it could either by nil or true or false. [Laughter] I find it weird. I haven't come to terms with the idea that this concept of pointers is mostly used - it seems to me - for that reason and that that's not some separate language feature.
Chris: [Laughter] Yeah.
Dave: It's sort of like, "Hey, this is -- really check if it's this."
Chris: Yeah. Really, really, really check. [Laughter]
Dave: I mean I like the idea, in a programming language. One of the things I like, in theory, about Go, is just like it makes you handle errors - or whatever. But I like the idea you're plugging it in and then you're unplugging it at the end. You're like, "Okay. I'm done with that pointer."
Dave: I want this to always kind of match up to this thing, but now let me back out. Now this can go away, this association. Yeah, no TypeScript. I had some Angular projects where I got by with TypeScript. I typed the right things to get through it. [Laughter]
Dave: Then, recently, I wanted to help out on this project that kind of needed to update some dependencies, and I pulled it down. It's like all TypeScript. I tried to use it. I'm getting thousands of errors and I haven't even started up the project.
I just was like, "I'm done. This is so stupid." [Laughter] Anyway, it wasn't a fun experience because I don't have the mountain of tooling in place to make it, do it correct. It's not a free thing for me.
Dave: Maybe we should read this question more thoroughly.
Chris: You know. There's a lot of momentum, as they well know, for TypeScript, and there's just more and more -- thus, there are more and more people on earth that are like, "I get it. Types are actually good." You know?
It was confusing. Lots of people had opinions about it. They said, "Oh, we'll just use comments," like JS Doc style to have it, which is not quite what they meant.
Dave: I like this proposal. There was a sense of optionality to it, like, you can just do it by comments, or you can just add these little colon number things to the end of it.
Dave: I think it's still not full-blown types like custom types.
Dave: And stuff like that, so I'm sure that's another one of those things. It doesn't meet the full needs. But I think it is interesting if this stuff can be kind of layered in.
Dave: For me, I think it is two things. It's optional, so I don't have to do it if I don't want to, which is cool. Then it also gets out of the tooling. I think what was saying a little bit before was that my problem is this tool chain is blowing up on me. If I could just avoid that, that would be cool.
Chris: Yeah. Reducing tooling is a pretty noble goal, I think. I didn't realize it. No custom types is tricky. I mean of course there isn't here with this really basic syntax. And they're just saying it's a baby step anyway, so maybe there is a way to do it.
Chris: We started the show talking about databases. What's a data structure? Well, it's a blog post, so it's got a title and a date and an author and content and all that kind of stuff. That's very likely going to end up as a type.
Chris: If it's GraphQL, it's going to start off right away as a type in your mutations and queries. When it comes back, if you're using TypeScript, you'll probably make it a type. Certainly, in this Go code I'm writing, and it's a custom type. This is a post type. I think, generally, in type land -- I mean, this is a guess, but I would guess it's about 50/50. It's not like mostly primitives.
Chris: If anything, it's mostly your custom types because they're more useful. Those are the things that you actually want to check.
Dave: Yeah, like, "Is this a user? Is this a blog post?" or something. It does look like, in the full Read Me, that they have a strawman proposal. They do have functions return a certain type, which I see is useful.
Chris: Awesome. That's my favorite one, actually.
Dave: Because I think that's a cool contract.
Dave: It takes numbers and it returns true or false or returns....
Chris: Now you're typing through your data flows, which is what matters.
Dave: --in transpilation we'd have to do across browser, but I would use this stuff. It just seems--
I think where I don't like it is all the angle bracket crud. But you know, whatever. If that's what it takes to get something working, that's fine.
Chris: You already did it.
Dave: Who knows, though. I think we're pretty -- I think this is helpful. I'm into it as long as it's optional and I can kind of use it. That's sort of the thing. You start using TypeScript and, all of a sudden, it's just very mad at you all the time.
Chris: Yeah. Think of the dance that has to happen, I mean the spec dance that has to happen, the browser dance of implementation that has to happen. But then there's all this tooling built on it too, so all the parsers, all the linters, all the formatters, everybody has to start dealing with the syntax all of a sudden. That's a big ass dance of people. To pull this off would be a real fricken' miracle. You know? You thought the picture element was hard. This is fricken' hard.
Dave: I could see it soaring through ECMA.
Chris: Yeah, and there are big people behind it. Yeah.
Dave: Yeah, soaring through ECMA and then I think the bottleneck probably might be getting it in Node. You know what I mean? It can go into V8 because Microsoft is using it, but making sure Node supports it all, that's maybe a whole thing. Then there's probably some collision with actual TypeScript.
Dave: Who knows.
Chris: You know it's because I've been working in my office here with Robert who is just a good developer for us at CodePen and has a long, interesting career. One of the things he works on is the UUID library on NPM that is downloaded like 20 billion times a second. You know?
Chris: It's so useful, and he's involved in the spec discussions around it and stuff and kind of lived through--
Now it's in browsers. It's Web cryptography, essentially. You can ask for a UUID in the browser now. That's pretty interesting. He saw the spec come together on that and continue to evolve.
Chris: That's a weird one.
Dave: Oh, yeah.
Dave: Right. There's a pipe. Then there's a big sieve.
Dave: A Babel that just fixes it all for you, so you type the new stuff and you don't even know you typed stuff that literally doesn't work anywhere. It just -- you know.
Dave: Whatever. It just went through the blurp-blurp machine and spit out something that works. I was always surprised to see, like, you know, you use the Babel REPL, and you'll just use something like question mark dot. What do they call it? The hmm dot, the optional chaining operator - or whatever?
Chris: Yeah. Mm-hmm.
Dave: All of a sudden, there are all these if statements and symbol iterators. And you're just like, "Whoa! I would have never typed the other thing, so I'm glad this exists."
Chris: [Laughter] Yeah, and that's funny. It's caused so many -- I wonder how many internal conflicts and conversations just the optional chaining has come up with. It ends up getting talked about a lot at CodePen because we're like, literally every time it's used, it feels good on the front-end because it's like, "Nice. I just saved this app from bombing out because I put a question mark there." But it's also saying, "Our data is unreliable."
Chris: I mean don't make too much of that, but it's kind of saying that. It's saying -- so, it always brings up this, like, "Why is that?" Every time you see a question mark period in a fricken' PR, the work that should happen is that you trace back all the way to wherever that little piece of data could possibly come from. It's better if you can fix it from never being not there - if you can. You know?
Dave: Yeah. Yeah. I've been dealing with this thing. It's that thing. It's like sometimes it's a number and sometimes it's a string - or something. [Laughter] You're just like, "Golly. I can parse INT. That's just fine." But if for some reason something doesn't exist, like - whatever - a bad data call or failed fetch or something, and I don't have data on this one record - or something. You know?
Dave: I kind of just want to bail out as easy as possible, like, "Okay. If it doesn't have it, it's undefined. Just skip it."
Chris: It's fine. It's fine. Yeah.
Dave: But it does present this thing. If you're like, "Give me the child-child-child prop," and it doesn't happen, and it doesn't come back as a number, now you need to -- your thing has to handle number and undefined. You know what I mean? I'm explaining it poorly, but I've just ran into some situations lately where I'm just having to jump through hoops to -- whatever is coming back can be a couple of different shapes because I'm trying to use this component in a couple of different places.
Chris: Oh, well--
Dave: Maybe sometimes it stacks. Maybe sometimes it's a number. And so, that's, I think, the--
Chris: Almost write it as an if statement then so it's not -- so it's more explicit, what you're doing.
Dave: Yeah. Here would be an example. Sometimes it comes back as 99%, and sometimes it's just the number 99, but I show the stat in a big thing. I have to do work to smoosh this stuff out. It's just been an issue.
Dave: Maybe types here, if I really embrace that, that would really save me.
Chris: Yeah, maybe. It's unfortunate that it's in two different ways. Honestly, one of these Go scripts I'm writing right now is to fix a little bit of data on one of our tables that just so happens to have that issue. Just a long, historical issue. It's not that big of a deal.
In fact, in your database, if you have sometimes it's a strong that says four and sometimes it's an INT that's four, Rails could care less. Rails is going to absolutely help you put that in whatever fricken' format you want. It's the most helpful thing in the world. You pull that out in Go, it cares a lot.
Dave: It super cares, huh?
Dave: Okay. Yeah.
Chris: It will just panic and fail if the type is wrong, so now you're in this situation where you're like, "Okay. Well, I can't say that it's an INT because if it comes back as a string and it's an INT, it's going to panic. So, I have to--" And Go doesn't even really have generics either, so you have this really convoluted workaround of making it an interface and then kind of forcing it to be an INT or string is way more of a dance than you'd want it to be. And now your type isn't very helpful because your type is just this convoluted generic thing. There's a lot of incentive to be like, "I'm going to fix that data in the DB so it cannot be wrong."
Dave: Mm-hmm. Mm-hmm.
Chris: Then if that data happens to be not just in the database table, which is probably already enforcing your type, it's kind of a strike against keeping JSON data in a DB because that's less typed. It's valid JSON either way, if it's a string or an INT in a piece of JSON. JSON doesn't care because JSON isn't typed.
Dave: Right. JSON is just like, "Dude, whatever you send me, I'm just storing it."
Chris: Yeah. As long as it's valid JSON, it's fine.
Dave: "I'm just the middleman. Yeah. I don't care."
Dave: Yeah. I think that's the problem we're dealing with, too, is sometimes it is that, like, input type equals number. What does it return, Chris? A number or a string?
Chris: Ooh, good question. That's some hot trivia stuff.
Dave: The answer might surprise you. [Laughter]
Chris: Oh, well, now it's going to be string, right? Is it string?
Dave: You got--
Chris: You got to parse INT it to get it?
Dave: I don't know. [Laughter]
Dave: I think you do. I think you have to parse INT it. But then also, if you set the step low enough, it can be a float because it's a dot. You know?
Chris: Oh, indeed. Yeah.
Dave: I think it just comes back as a string because HTML is like, "I do strings very well. I don't do the other stuff." You know?
Chris: Right, and then it depends on what backend crap it's going through and what database it ends up in. You know?
Dave: It does feel like 90% of the job is just massaging data into one form to get it out to another form to get it out to another.
Chris: Right. It has really sucky tendrils. There's -- I feel like -- a very strong incentive to not deal with it. If you see front-end code that is coalescing some type into another type, it's code smell. It needs to have a big comment there that says, "Important to-do: Fix actual data. It's not a front-end job to be dinking with this data." You know?
Chris: Because you're going to do it there, and then you're going to do it in the next component that you need it, and the next component you need it, and wherever. That's what I mean by the tendrils of it. I'm starting to have stronger opinions about this.
Dave: You're building up.
Chris: In the past, I would have been like, "Oh, I don't care what the back-end sends me. I only have one skill, and it's accept data and turn it into UI, so I'll do whatever I need to do to do that." The more full stack-y you get, the more you're like, "No. That's bad news."
Dave: No. No. We're going to make that the right one. Yeah. No, that's a great point. We're used to, on the front-end, just, like, "Whatever you send me, dude, I'll make it work, man." You know?
Dave: We're the shaggys of the group. "Hey, man. We'll make it work."
Chris: If you have a middleman anyway, which is kind of like what I feel like your API could be, especially a GraphQL API, you can have this general philosophy that says, like, "I'm going to do the work at the GraphQL layer in my app to munge this correctly."
Chris: I'm not going to send back something that the client has to think about. You know? An example of that is URLs. We made this decision long ago that the client never has to put together--
You know you're like, "Well, I need to output the link to Dave's profile, so it needs to be codepen.io/davetron5000." You have the username in the data, so you could be like, "Oh, I will just craft together this URL. The string will be http://codepen.io plus username. Got it!" You know?
Chris: We never do that. We never ever do that. You return a field in the GraphQL that's profile URL and then you use it.
Dave: Oh, yeah, yeah.
Chris: You keep all that logic level at the API level, which is nice wherever I need to change anything.
Dave: You're not doing concats. You're not concatting.
Chris: Yeah, and that's just one example. It could be anything. If you need a preformatted chunk of anything, do it at the API level and then just use it.
Dave: Mm-hmm. Man, that's inspiring. Actually, I should probably do that more.
Dave: I did do a thing. We were fetching data, and you have pages or posts. It's like WordPress posts. It's like posts. In the UI, you can relate posts to different posts, like I'm going to relate this post to this post to this post.
Chris: Yeah. Yeah.
Dave: Like a quote and a gallery post or something like that.
Dave: Then you can display them all together. Well, the way you'd use a has and belongs to many -- like a two-way relation, has and belongs to many relation, and so you build this whole other table. You have an A column and a B column. You say, A ID and B ID are related.
Dave: But then sometimes it's ID equals two and ID equals three, but then you can also end up with ID equals three and ID equals two (in the AB columns).
Dave: You have a double relation, and so I was just like, "Ah, crud! How do I do that?" But in that data layer where I'm using Prisma as my intermediary, you know, like in the API.
Dave: But at the API layer, I just was like, "You know I'm going to sort these," so it's always going to be two-three.
Chris: Sort put you put it in?
Dave: And so, if two-three already exist -- sort it before you put it in. It's really weak, but what happens is, now in my response, I have a related lower and a related higher. Then I have so smash those together and be like, "These are just relations," and so I return the relations in the response. The user interface never even knows about related lower or related higher. That's only a database issue.
Chris: Yeah, that's the right place for that.
Dave: So, I kind of moved that out of the front-end.
Dave: It took me a few loops--
Chris: So, an alternative would be to go fix it in the database and then not munge it ever. Just run--
Dave: Right, right, and I think you can. There are indexes or whatever I can do in PostgreSQL to make that never happen. But now I'm doing database operations, so that's not fun.
Chris: Right. It's technical debt one way or the other. You know? Mm-hmm.
Dave: You know, and maybe I can do it in the database one day and then rip out my code later, but I'll still need that step of, like, yonking out -- or whatever -- maybe merging two different things or something. Anyway, it's all very interesting.
Chris: [Laughter] Yeah, where do you make your data safe: at the DB level, at the pull it out of the DB level, at the API level, at the client level? You've got lots of choices, man. The deeper you go the better, probably - generally.
Dave: Yeah. Yeah. Well, I don't know. The less your front-end has to do seems like old advice that we kind of dipped away from, right? [Laughter] Make your front-end do as least as possible.
Chris: Yeah. Turns out servers are useful. [Laughter]
Dave: Well, cool. We should wrap it up. My dog is ready to go. She just shook. [Laughter] Did that come up on the mic? I hope so.
Chris: It did a little bit.
Dave: Chris, boost it. All right, there it is, so she's ready to go. So, we're going to wrap it up. Thank you, dear listener, for downloading this in your podcatcher of choice. Be sure to star, heart, favorite it up. That's how people find out about the show.
Follow us on Twitter for 16 tweets a month. And we've got YouTubes over at youtube.com/shoptalkshow. Join us in the Discord, patreon.com/shoptalkshow. Chris, do you got anything else you'd like to say?
Chris: Hmm... ShopTalkShow.com.