Building websites is cool again, but what threat is there to all of us from AI created images? And how would you design an API in 2022?
Time Jump Links
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 websites. I'm Dave Rupert and with me is Chris Coyier. Hey, Chris. How are you doing today?
Chris Coyier: That's right. I'm doing pretty good, man. Just a normal show.
Dave: I watched your--
Dave: --talk the other day about--
Chris: Oh, you watched it?
Dave: I watched it. I've seen it before, but I also wanted to see the short version.
Dave: But it just got me amped up again, man. Websites are good now.
Chris: Yeah, I put a lot of work into it because I freshened it up and trimmed the fat and whatever. I'm going to be redoing it (not entirely) because it's one of those talks where I feel like it could be a forever talk. I know you've probably had that moment too where you're like--
Dave: Ooh, I've got that one.
Dave: It's my prototypes talk could be my forever talk. I just want to talk about that for the rest of my life.
Chris: And you can, and that's not a copout. That's a good thing. It's like Jeremy Keith talking about progressive enhancement. He's not going to stop doing it.
Dave: [Laughter] Oh, man. Here he goes again.
Chris: But the talks change because the details can change. How it resonates can change. You can put in different metaphors and stuff. You can have a lot of fun with it and still say this matters and this is the thing that I care about the most and that I'm well suited to tell you about.
Chris: There'll be an endless supply of human beings to hear that message.
Chris: You really don't even have to change what you talk about. My message isn't almost as clear as yours. It's this kind of like -- at the end, I get to it, and I think I almost need to extend the ending to dwell on it or make it the beginning, possibly. I like when you kind of pick up and move stuff.
Dave: Modular talk design. Yep. Yep, that's my new book on A Book Apart. [Laughter]
Chris: Yeah. Almost like a positive message like we're figuring it out. Some of the stuff that's happening on the Web is because it's not as new anymore. And because it's been around long enough, we've kind of collectively figured out the stuff that we need.
Chris: Whereas in the early days, we were just a little ignorant of what we were going to need. The various things have shaken out and be like, "Okay, this is the set of stuff that we need."
Dave: Yeah, well, it's like Mark Andresen was just like, "I just invented image. Boom. Put it in." People were like, "I don't know about that." You know? [Laughter] It's like, surprise, 30, 40 years later, the Internet is just images.
Dave: So, how important was that?
Chris: Stuff is going to keep changing, but the stuff that we're getting now has been a reflection of, like, okay. We figured out what we need. Now let's start putting it in the browsers and building it into the tools we need. We're like, ah, a breath of fresh air. You know? Good job, team. We've done it.
And so, I can keep saying -- I can keep pointing to that and be like, "See this? See this? See this? It's a lot better now, right? Good job, everybody."
Dave: I feel like you've done plenty of talks that are like CSS is cool. You know? You obviously had CSS-Tricks. You're the CSS guy. But not quite CSS wizard level, but you're the CSS guy.
Chris: Um, right.
Dave: But I think this talk is an extension of that, but it's almost like, "Hey, CSS is really good." You've gone from, "CSS is good. Look at all these tricks or effects I can create," to, like, "No, CSS is really good."
I think you were showing -- I hadn't seen that where you cycle the images on your little burrito site.
Chris: Oh, sure. Yeah.
Dave: They flip around on mobile and stuff. I think you're using offset. That wasn't an offset path you were using.
Chris: No, that was another one.
Dave: Or flip. You were using GreenSock or something.
Chris: You know, interestingly, I bet you could use offset path there. Yeah, that was when I was trying to showcase flip, and flip is just such an interesting concept specifically because it brings tweening to the Web.
Chris: I don't need to know exactly where elements are right now or where they're going.
Chris: You can say, "Just look at where they are right now. Then move them." Then say, "Okay, now animate between those two states."
Chris: That's great.
Chris: It started out as being an efficient way to animate.
Chris: It was like, let's use transforms and opacity and all that stuff, and then we'll put it in the end state, and then we'll reverse it and all this stuff. That's how, conceptually, flip began as a concept. I think it's morphed into, like, don't worry about all that. That stuff is boring and rote and can be handled by technology.
The mental model of flip is what's interesting. The mental model is: Don't worry. We'll tween between two. We'll tween any DOM anything between two positions.
Chris: That is cool and crucial.
Dave: Yeah. I hadn't seen it so effective, I guess, because you're just cycling a CSS class, but then this little -- it looked little. It could be gigatons of GreenSock. But it was just an oomph. You know? It's like the sound effects. A little swoop.
Dave: You know?
Dave: You just added a tiny effect that makes it just feel rich.
Chris: Somebody could do a talk of 15 ways that flip helps - or something. I would like to see that. I wish I could dwell longer on that section. I wish I could dwell longer on the typography section. There are all these things that could be turned into longer talks.
I almost encourage that for new speakers. Definitely don't try to cover all of CSS in a talk because you're going to do a bad job and people will--
Dave: Give a talk on container queries.
Dave: Or do a talk on--
Chris: Border radius or whatever. Go deep instead of wide. I'm kind of forsaking that advice here. But I'm not trying to cover all of anything. But I do move on a little quickly and part of me desires--
You know I once did a talk in 45 minutes -- or maybe it was an hour or something -- on just the before and after element in CSS. [Laughter]
Chris: But I loved that because there's so much to say.
Dave: Oh, man. That's like Estelle Wyle levels of, like, I am going to just go painfully deep on this one concept here for you.
Dave: She can do it off of memory. She's just like, I have the spec memorized. It's fine.
Chris: I know. She almost annoys me in that I'm always like, "I know what Estelle knows. My god. We're the same." Not quite the same circles, but we just look at CSS stuff. But inevitably, she'll always be like, "What about this?" And I'll be like, "What?!"
Chris: There's that?!
Dave: She's like--
Dave: Yeah, it's like, well, if you turn on bi-di, it'll emulate the GPU and blah-blah-blah.
Dave: You're just like, "Huh?" That's not true. I just tried to be a pretend Estelle.
No, I think that's cool. I think it's funny with talks. It's like what I've tried to come down to is can I make it personal. Can I make it something about me and what I care about too? I think I made the mistake of talking about stuff I wasn't--
This is maybe like imposter syndrome or Dunning-Kruger or something going on, but it was just stuff I was just like, "I think this is a cool talk." You know? But I think the more I've done them, there's nothing that can replace you just talking about the thing you super like.
I think if you are talking about something, you kind of know. It's harder. But something you like goes a long way.
Chris: That's a good point. Yeah. Yeah, draw from reality, too. Even if you think your job is boring or something, at least you lived it, so you can really clearly talk about it.
Chris: Yeah, that's good stuff. Good luck, everybody. Conferences are coming back a little bit. I know COVID numbers are not exactly zero, so tricky-tricky as we approach the winter. But getting there. We're getting there.
Dave: Yeah, I mean I think it's going to be a diaspora consolidation kind of thing. we're all going to go and try conferences, and then we're going to say, "Woops," and then we go back. It's just going to be that until the engine gets started back up, the engine of society.
Chris: Yeah. Well, me and you both are going to be in Denver, Colorado next month for one.
Dave: Yeah. Soon.
Chris: And I am looking forward to it. [Laughter] Yeah, I've got to get going on that. Looking forward to it. We're going to do one of these too, a ShopTalk Show there.
Chris: There'll be a show. So far, we've always published them.
Chris: And they have a different kind of energy to them, so I hope you all look forward to that because we're just even jokier, I feel like, in real life.
Dave: Well, it's funny too. For me, it's always this, man, we don't do this in person that often. [Laughter]
Dave: There's this moment of, this is weird. I'm looking at you physically. This is different. [Laughter] This is a different world.
Chris: I was listening to -- I subscribed to the Stratechery by Ben Thompson and John Gruber do a little paid podcast, which is the first time I've ever subscribed to a paid podcast in my life, but I like their model in that it's 15 minutes long.
Chris: They start a little timer, and it's no more, no less. I think that's kind of clever. There's something about that timing makes me always be like, "Ah, I'm going to listen to that," because it just happens to match up with some of my time in car stuff.
Dave: Oh, that's a commute. Yeah. Yeah, that's good.
Chris: Yeah, it makes me a little jealous in that way. They always fricken' find some way to do it right.
Anyway, they did one recently on the art generation stuff. I'm talking about DALLE and MidJourney.
Dave: Stable Diffusion.
Chris: Stable Diffusion, yeah, and then I was just hearing more and more about it. This isn't brand-brand new, but it feels pretty brand-brand new to me because it's only, what, less than a year old of what's been a tech news story. It's like every week there's some interesting development, and it's just been more and more fun for me to follow over time.
At first, I'm like, "Oh, DALLE. Maybe I'll get on the wait list or something." Then I'm like, "No, because then I'll get the email, and it'll be one more thing." I'll type in racoon with a rainbow hat farting cheese, or whatever, and I'll laugh for two minutes. Then I'll be like, "Why did I even care?" Do I even care about this? I don't know.
Dave: Right. Right.
Chris: But then I was listening to their show, and they were like, "Oh, this one MidJourney is all on Discord." I'm like, "I'm on Discord."
Chris: What do you mean it's all on Discord? How does that work? [Laughter] But it's just literally how it works. You click one button. You're instantly in the Discord. It's instantly like, "Oh, you want an image? You type /imagine and then type some words and you get an image based on what you said.
MidJourney is one of them that's so cool and so art driven that almost anything you type in there is going to be awesome. And you're watching other people do it, so you're seeing what their prompts are, their spells, which I'll agree with the entire Internet. That's like the world's coolest way to refer to typing in some words to make an image.
It's just outstandingly fun. The first thing you experience is, like, woo, fun.
Chris: I just think it's interesting, and I know there's all kinds of nuance that I can't speak to intelligently about it. But then I was on a longer road trip yesterday and listened to the Changelog.
They had Simon Willison over there, who has been on this show in the past as well. He's really much more educated about it all and was just waxing poetic about how interesting all this stuff is. It's just got me kind of excited about it. Have you played at all? I know your partner in crime Trend is a MidJourney fan.
Dave: Trent seems to be in the MidJourney Discord and knows the right stuff to type. I played with it. I think it was a DALLE 2 thing. I joined the Discord, but I didn't figure out where to type the thing to make it do the thing. [Laughter]
Dave: I kind of wanted some private exploration and it felt like it was going to blast it out very public. You know?
Chris: Oh, yeah. It's public, unless -- I think you pay whatever, $5, and then you get a private channel.
Dave: Oh, really? Okay.
Dave: Maybe I'll do that just purely out of, like, I want to type dumb shit and see if I can break it. Not X-rated stuff, but just what can I make it do. I want to experiment, so maybe I just need to do that.
Chris: I don't know how the X-rated stuff works. I assume, on Discord, they've got that all turned off. I know on Stable Diffusion, now you cannot remove the X-rated filter.
Chris: It's not producing boobs on trees or whatever.
Dave: Darn. Okay. Sorry. Scratch out that part of my whole business plan.
Dave: Yikes! Okay.
Chris: I imagine the X-rated angle to all of this is going to explode at some point. That's twisted to me. I mean whatever. It's not that I'm not interested.
Dave: Well, any new technology, you have to think about how is it going to be used maliciously, or how is it going to be--
Chris: Used for porn.
Dave: Used for porn. But then it's like what does this do? I don't know. I think a lot about the ethics of it, too.
Chris: Well, let's do that then. The big ethical angle, there's several. One of them is people losing their jobs. Another one is how did you train this thing. You trained it on my art that I did not approve you doing it. Those are two big angles.
Dave: Yeah. I think robots are going to take my job.
Dave: I think there are big, global implications. Ethan Marcotte has this really good example in one of his talks where big company X goes to Kenya, pays Kenya's dollars a day to train an AI that's basically just going to take their jobs. Then that whole market gets wiped out of jobs.
I think I get mixed up in there's this element. I want to do these almost like sci-fi book covers for these short stories I've been writing on my blog, right?
Chris: Ooh, this is a perfect one. Right? That is a job. I could see you hiring someone for that, theoretically.
Dave: Chris, have I actually tried to hire people? Yes, I have. I've actually been like I have $500 of cash for this dumb thing I want.
Dave: Does anyone want to do this? I had no takers. As a result, I now follow a bunch of very cool sci-fi people, so that's cool.
Dave: So, got that going for me.
Chris: Sure. Can you imagine a world where you'd pay $500 to somebody who is excellent at using these tools to produce one for you, or does that feel like, "Ah, you didn't lift up a pencil to do this"?
Dave: Well, that's where I struggle because I don't think it's a $500 object to me. A $500 object in Xbox that I'm going to put in my home on my TV stand and it's going to work for the next ten years.
Dave: It's going to play awesome games and give me awesome video game memories or something like that. That's a $500 object.
A JPEG on my website does not feel like a $500 thing. Does that make sense? If I could get AI to kind of just vibe something close enough -- or you look at Trent's stuff, that's actually very good, high-quality stuff.
Dave: That's better than some concept artist stuff, and of higher quality. How do you--? Could I just do that and be happy? Let's say it cost me $5. Am I happy?
I think, as a consumer, I very much am because it was a lot cheaper, but I realize this theoretical person who could have made $500 but never emailed me back, they're out $500. You know?
Chris: Doesn't that remind you of the $500 website? That world is gone. It's gone. It used to exist when we started. Those jobs are gone now. They're just gone because Squarespace ate them.
Dave: Squarespace, Wix, Webflow, yeah.
Chris: Anybody's, I'll say, minor -- I'm not trying to be a jerk, but minor -- ethical quibbles over this is not going to stop this train. That was such an interesting point, though. Was it Charlie Zarzel who was writing for The Atlantic was sick of using Alex Jones's Getty images thing because that's the only one on Getty images. Says, I'm going to use an art creation tool, to use a new one, used it, looked great, and then just got speared for it. But he got speared for it because The Atlantic has a zillion dollars. It's a huge, mega magazine, and the act of hiring illustrators for posts is an established media practice. All of a sudden, he throws it away and gets an image for free.
Okay. You can apologize a little bit about that or you maybe been more upfront about how that went down, but that's going to happen. The train has left the station.
Dave: Right. Right. Yeah, so now there's this whole industry of whatever.
Chris: It's going to take your job. Yep, it's going to take some jobs.
Dave: Verge hero image smiths that are out of the job.
Dave: That sucks, you know.
Chris: Think of all the time we spent talking about social media image cards.
Dave: Oh, my God.
Chris: We could have fired those through.
Dave: I think somebody is doing that. I saw a post.
Chris: Is there?
Dave: Somebody is just letting whatever. I think it was maybe Stable Diffusion. Just make an image.
Dave: He was like, it was better than the stuff I was creating by hand, which is just cool.
Chris: Do you think we'll hit a fatigue point, though? At some point, if you have 500 of them, and every single blog post you have has it as the hero image, I think our collective brain will start looking at it and be like, "Oh, that's one of those images."
Dave: That kind of happens with Unsplash and stuff, which are taken by humans.
Chris: Totally. I can look at an image and just be, "Meh, Unsplash." [Laughter]
Dave: I'm just like, "This is so boring." Web.dev did that for a while.
Chris: Hmm... Conventionally attractive white woman with wide-brimmed hat walking through hay.
Dave: Sunset with rocks. You know?
Dave: I think that's done, too. It may hit peak interesting. But what's interesting about these Stable Diffusion and MidJourney is you can say, "In the style of Matisse or Van Gogh."
When my woman walking on the beach image gets tired, I can say, "Yeah, but do that in the style of a Bauhaus artist," or something like that. It's just going to make something weird.
Chris: Yeah. Right.
Dave: Or Salvador Dali - or something. They are getting very smart to the point if you wanted to hire somebody who does art in the style of Salvador Dali right now, Chris, how do you do it? You have to go to, like, Dribbble or Behance.
Chris: Yeah, I suppose. It'd be a really specialty job, and it would be hard to find. Your only criteria was generic sci-fi style illustrator. Even that was too hard.
Dave: Isaac Asimov style image or an Atari box art style image. That's, I think, what I was going for. But yeah, I got crickets, man. No one even emailed back.
Chris: Yeah. There's no way you're going to find a Dali impersonator. That was part of Simon Willison's chat, too. Apparently, there's some really wonderful painter, perhaps, gets hired by Wizards of the Coast to draw Magic Cards and whatever, like those great sci-fi fantasy dragon style.
Chris: I think there's a bit of a phenomena where people don't really know who he is, but they've learned, in the Discord, to put his name in the prompt because the result then is super rad. That's all they know. [Laughter] They know this guy's name equals sweet art.
Dave: Here's what I wish from. I think the other ethical side of, like, these were trained on free -- on artists, and that did not get paid. I think that's actually kind of a problem.
I think Copilot has this same problem, right? Like, "Oh, cool. You trained Copilot. On my code?" [Laughter] "I contributed to the robot? That's interesting."
Chris: Isn't that weird, though? What is Google Image Search doing? It's just barfing out images that it also has scraped.
What if I forget who made this? It was probably Adam, I think, was like, "What if I'm an artist and I page through a book of art and then my brain uses that to learn art, and I paint in the style of that person? Was I stealing from those other artists?"
It's like, no, that's an Austin Kleon thing, right? Great artists steal.
Dave: Great artists steal. Yeah. Yeah.
Chris: I don't know, but this is stealing on a much more rapid pace. The size, scope, and speed of the stealing has accelerated.
Dave: And quality. Yeah, and quality. Right? When Austin Kleon steals, I still know there's a human in the process kind of munging stuff together.
Chris: Yeah. Yeah, yeah.
Dave: Cut and paste or painting and brush. But yeah, when the robot steals, it does it very fast and very quickly.
Chris: Yeah. I was thinking of how -- I was captivated by thinking about all this and playing with the tools and all that. I had a couple of final thoughts, and then we'll get back into some Web tech stuff, I hope. [Laughter]
Chris: One of them was the usage of it for places that you'd never hire an illustrator anyway, like the social media cards. Nobody is going to pay $100 a card or whatever. That market has just expanded.
One of them was, at the time, we were putting together a "save the date" for our kid's birthday party.
Chris: The art on the little e-vite invitation thing was so dumb and bad, the default ones. It's going to be kind of like dark theme, so glow sticks and LED lights and stuff. We're going to make that the theme and make it kind of fun that way.
Chris: And so, I was typing those types of things into the prompts, and it was producing such super cool stuff. I was like, I'm absolutely going to use this as some of the art just as the background of the e-vite. Maybe I'll print something for the tablecloth or something.
Under no circumstances would I be hiring someone to do this. Nobody is losing a job over me using some interesting art for a birthday party.
I'm sitting next to my buddy. I'm showing him the Discord. "Look at this. Look at how interesting this art stuff is." He's not really a tech guy. More of a lawyer.
He's like, "Oh, you know what? I've often thought of this, and I'll never do anything about it because I just have no idea how to do it, but I call one of my kids "Bear." I call my other kid "Robot,"" which sounds rude, but it's actually a clever twist of words for her real name - or whatever.
Chris: Bear and Robot, and he wanted to get some art or something that showed a cute bear and a cute robot holding hands or something, some kind of thing to remember his kids by in an interesting, cartoony kind of style.
Chris: I was like, "Man, I'll tell you what. Your wish is these tools' command." [Laughter]
Chris: You will get it. I was doing it in MidJourney, and I think MidJourney is not the right one for it because it ends up being a bear with pink laser eyes and stuff because it's very -- future art is the real sweet space for MidJourney.
Dave: Sweet spot for them, yeah. Yeah, yeah.
Chris: But Stable Diffusion is much more like it can just do anything. Not to mention can you run it on your local computer, which is insane.
I have an M1 Mac, and apparently, that's about the hardest infrastructure to run it on. But I'm going to do it one of these days.
Dave: It just came out, I think, a stable build for M1s and M2s. But yeah, that's like the thing, too. I think Christian Heilmann, I saw a tweet from him. Apparently, it burns quite a bit of electricity to do this, to generate an image. I wonder, too, if there's an eco-concern if we're all just making GPUs glow-- [Laughter]
Chris: Yeah. There is some connection between this world and the--
Dave: --in order to put boobs on trees or whatever.
Chris: --this world and the crypto world. I imagine. I can't prove it or anything, but I imagine it's a far cry from anything blockchain related.
Dave: Oh, yeah.
Chris: But it is interesting how they both have such interesting ethical concerns. Wouldn't it be nice for somebody to invent a technology one of these days that's just morally and ethically fine?
Dave: It's a--
Chris: Everybody, "Ah, it's fine."
Dave: It's a free electricity maker. I don't know.
Chris: Yeah. [Laughter]
Dave: It seems -- it's actually super great. It doesn't pollute anything. It just makes electricity. Desert planter. It puts plants in the desert. It's so interesting.
Chris: It's just art now, but the technology is similar, right? It uses these AI-based things to have neural pathways and rates the results.
Chris: It's all very interesting. I've seen good talks on it. But it's similar to how GitHub--
Now we're experiencing AI help us in lots of ways. For example, we have spam catcher tools at CodePen that are AI-based.
Dave: Yeah. Yeah.
Chris: That Alex has been working on that get trained continuously from new spam that is identified through it and that we identify and correct.
Dave: Yeah, okay.
Chris: Correction is an important aspect of these algorithms. We're experiencing through GitHub Copilot. We're experiencing it through the MidJourney Discord and stuff. We're experiencing it more and more. This world is booming hot.
Chris: And it's starting to be like it's going to capture people's imagination. It's like what else can it do. Can it build a house? Can it fix cancer? What's going on here?
Dave: You know we had Paige Bailey on episode 299 to talk about machine learning. The one thing she said, it stuck with me. You have to retrain the AI. Kind of like what you're saying. You have to train it, like, "Hey. Whoa. You went too far."
It's interesting. Is a job in the future going to be AI trainer, or maybe that's already a job?
Chris: You'd think that, like in the Discord, the number that people pick -- because the way MidJourney works, it gives you four options.
Chris: You pick, oh, do I want variations on number four or number three, or am I happy with it? Then even upscale it, too. You're like, ooh, three is perfect now. Give me a high-res version of number three.
Is that training the model? I have a suspicion that it's not. The fact that you download Stable Diffusion offline and use it, I have a feeling that information is not making its way back to the model either then.
Dave: Right. Right.
Chris: How is it being--?
Dave: I don't know. I guess, no, just different training data or whatever because you're adding training data, like that spam is a bad spam. That spam is actually a good spam.
Chris: Yeah, that has a very clear, like, black or white.
Dave: What about these image things?
Chris: You'd think even in MidJourney, by virtue of you picking the one to make more variations from, that's a signal that it's done a good job and you like that one that it did.
Dave: Nah, I mean this conversation has come up at work. It's one of those steps of technology where you have to pay attention.
O'Reilly Radar had these four terms, like pay attention to, ignore, move away from, or hot or not for technology.
Dave: It does seem like you're going to have to start paying attention to this because I think it could be foundational. And I think just even more amazing.
When I was a kid, I didn't think I would be confronting AI robots. You know? I think it was always sci-fi, but now it's like, "Oh, man. This is happening now."
Even when Paige Bailey was on four years ago, it was kind of like, "Well, maybe one day." Now, four years later, it's like, "Oh, this is turning into the job, kind of?"
Chris: I think it has more potential to do interesting things, to me, than anything blockchain related. Sorry, Web 3 people, but I'm so bored by that. There's so much time and effort and energy and money has gone into that world with nothing interesting -- sorry -- to me, at least -- out of it. Whereas this is also new, interesting, sexy, uncharted, interesting, and already we're seeing all kinds of interesting things come out of it. Can this world please suck up some of the intelligence of the next generation of programmers? That would be great to see you go this direction, not the fricken' crypto. Sorry.
Dave: Yeah, well, and it's weird. They are not related, but they kind of are. The big thing about NFTs was you get this art, and you own it. Then DALLE comes along, and it's like, "You get this art and it's free." You know? And kind of higher quality based on what I saw - most of them.
You looked at all the NFTs, and they're really just procedurally generated variations of some kind of laser eye hat mouth.
Dave: Now I have a robot that can print anything I want. Big Ben in the style of whatever - Picasso. It's cool. I like that future. I like that creative tool more than the "I bought a cool avatar future," I guess.
[Banjo music starts]
Chris: This episode of ShopTalk Show is brought to you in part by Split. That's split.io. Split.io/shoptalk, actually.
A very clever name for a product because it has to do with splitting the users that use your website. Imagine a basic use case of that being something like A/B testing. I want to show some percentage of people this version of the website because I want to test the effectiveness of it without necessarily rolling it out to everybody. Test the effectiveness meaning literally measure the impact that it has and see if it's kind of good or bad.
It gives you that ability in your code, but it separates the ability. You don't have to deploy in order to change the 100 people or the 25% or something. You manage that elsewhere, which ends up being a pretty nice experience.
Then again, it's for rolling things out. You have a brand new feature. You don't want to roll it out to everybody. You want to roll it out to a subset and get feedback from them. That's the whole point of feature flags. Split helps you do that.
Split is the feature delivery platform you need to help execute these modern expectations and continuous and progressive delivery because if you're not delivering, you're falling behind. You and a team of ten can create your first feature flags at split.io/shoptalk. Create your first feature flags with a team of ten. Thanks for the support.
[Banjo music stops]
Chris: All right. Here's some Web work.
Dave: All right. All right. Give me...
Dave: DHH is kind of weird, so--
Chris: [Laughter] True. True. Get a way from all that. [Laughter] God, there's so much there.
Chris: Anyway, we've been moving to React for a long time - a long, long time - and it's been fine. Better than fine, really. This is clearly the right path. I don't regret any of our technology choices. Whatever.
Rails actually powered our GraphQL API. That's what we chose when we chose those technologies long ago. Even though we are switching to React, we're still using an API that was powered by Rails. Rails handed the route. Rails responded to the request and did the auth and used--
We used some kind of GEM or something that was like this is the language that you use to write all of the code that responds to the GraphQL. There's a bunch of effort and work and tests put into that world.
Moving off of Rails isn't just like moving your controllers and your views. It was replacing an API also. We've been like, "You know what? Let's chip away at this. Let's make a Go-powered GraphQL API moving forward," and we have some experience doing it. We've already created one that we use for our admin tools and stuff as a test run building a Go GraphQL API.
Now we've been chipping away at it much more seriously, like, let's just finish or get close to finishing our existing API but in Go. If that seems like a simple job to you, you'd be simple wrong. Replacing an API kind of side-by-side with the one that already exists is a lot because it's your job to make it one-to-one.
Chris: Like this new API has to be identical to the other API even though it's in a totally different language. You know?
Chris: Tricky because the languages of Ruby and Go are just real different.
Chris: Sometimes Go is really quick at expressing something. Usually, it's absolutely the other way around. You look at a one-liner in Ruby, and then you're like, "That's 50 lines in Go."
Dave: Yeah. Yeah.
Chris: Anyway, I find Go easier to follow, reason about, and all that stuff. But it's really taken quite a long time to work on this project, making it exactly the same. I think it's more work than creating the API to begin with.
Chris: To begin with, it's greenfield. You just write the API and it exists. Now it's like, "Ooh, we have to write that same API but sweat the shit out of the details and make sure it's exactly the same in this new thing."
Dave: It's painful. Nuxt 3 -- right now, our API is an express app, right?
Dave: That's the file structure, and it builds out your API, and it can chuck it out to a serverless function. We were kind of just experimenting with, like, could we move to Nuxt 3? Let's just see what it's like. The API refactoring was...
Chris: Constant journey, yeah.
Dave: --was a big one, man.
Dave: Yeah. It was just like there's no good way. This is such a huge refactor. There's not even a strategy to just pluck routes off. It was like this is a huge, gnarly boy.
Dave: I'm trying to be positive, but it was just like touching the AI is--
Sorry. Not the AI. We were just talking about it. Touching the API is such a tough situation because it's the brain. It's the nexus point for your whole app.
Dave: Operating on it or trying to replace it is really hard, and replacing it route-by-route would be awesome, but that's harder.
Chris: Yeah, that's weird. [Laughter]
Dave: You know?
Dave: Now you've got some kind of server router mixed in.
Chris: It's interesting that you care, like that express handling. All that routes is actually a pretty important aspect. You must be talking about a Rest-based thing - pretty much.
Dave: Yeah, it's a Rest-based thing.
Chris: If it's GraphQL, there's one URL. It's just /api.
Dave: Yeah. No, I mean I guess you're trying to sell me on GraphQL again.
Chris: No, I don't care.
Dave: I'm just saying no. It's a dumb... [laughter] It's a big, dumb antipattern. No, I'm just kidding.
Chris: I think it's usually the wrong pattern, but it's just not for us because it's just worse.
Dave: I think it's actually super useful, but I think there's too much. You know? I don't know.
Chris: Yeah, it's a lot of code, man. There is no magical part to it. I was going to talk about some aspects of it that are a little magical. Not front-end related, but I haven't been touching the front-end at all, like none.
Dave: Because there's that whole aspect of using the GraphQL once you have it.
Chris: I think there are probably a lot of people out there that are pretty good at GraphQL using it. The API already exists and it's now your job to implement it in an app. That can be a lot of work.
Chris: You can kind of just use it, but chances are you're using a library of some kind, like Apollo or something. The point of that is it has stuff that you would just suck to write by hand or you just couldn't really, like all the caching of queries.
One of the aspects of it is, for example, here's a query that everybody has got. It's the session user.
Dave: Mm-hmm. Yeah.
Chris: The session user knows the name of the logged-in person. It knows the avatar URL that you should be displaying, right? As you're building out componentry, you can write queries that have a session user as part of the query. There might be 50 of them in different components across your app.
Apollo is what solves that. If you have nothing to solve that, you're going to make 50 URL hits against the API for the session user. Apollo is like, "No, no. I see what you're trying to do here. I have 50 queries trying to query for the session user. I'm going to combine them into one."
Chris: "Get the session user, put that into the cache, and then all the rest of these can -- I will hand-sprinkle this information out to what is needed." That's clutch.
Chris: Clutch. It means, as a front-ender, I never have to think about the efficiency of the API usage. I just ask for whatever the hell I want and it will make it efficient.
Chris: It will batch it. It's just very clever in how it handles it.
Dave: No, that's a good point. I guess, yeah. Is your API--? We all write perfect code. One thing I think we're dealing with, with our API, is like, "Oh, well, you've got to be an authenticated user to hit the API," because most of our routes are protected.
Dave: Then you're just like, "Oh, okay. I've got to invent a user." I'm finding even testing the API or operating on it without a Web session is kind of tough because you're just like, "Oh, I need to send this--"
Chris: Yeah. You should build a little tool for it.
Dave: Yeah, because I'm just like, "Man, it would be a little easier if I could just use PAW or whatever," but then my users are all mixed up. I know I could get a JWT or session. But I don't know.
I'd love if I could be anon. You know? I'm anonymous right now.
Dave: Treat me as whatever default.
Chris: There's this tool that just ships with GraphQL called GraphiQL.
Chris: It gives you this little Web interface for your own instance of GraphQL that it just sits there and has a little API tester. It's a pretty crucial part.
It's interesting. It's useful both for the front-end people and the back-end people doing it. It's been so interesting for me being a back-end person. My big great switch here to be writing the resolvers and the logic and the database methods and stuff that make the GraphQL happen. That stuff does not just appear. There's not just a database and then you have GraphQL APIs to the database. That is not the case.
Chris: It is all very hand-written.
Dave: That's why I don't do it - what you're describing. [Laughter]
Chris: Yeah. It's a ton of work. It's an absolute ton of work. And a couple of things.
One is that auth isn't just, "Are you logged in or not?" A good API has a permissions model so that every piece of the logic is not just, "Do you have permission to be using this API?" It is, "What things do you have access to?"
Dave: Yeah. We have an "Is auth'd," and then we have a thing we made called the bouncer.
Chris: There you go.
Dave: That just basically is a bouncer at a bar. It's like, "Here, get out. You can't be here."
Chris: But it gives you this opportunity to write logic in the bouncer call for specific things. CodePen has some funky, funky, funky logic sometimes, and we're trying to make this model really great for the future because we're just very future-focused on everything right now.
One of them is, okay, you can collect things on CodePen, right?
Chris: You can take a Pen and put it in a collection. You can take a collection and put it into a collection. Collections are these very interesting things.
Dave: Ooh, meta.
Chris: Right, and things can be private or not private on CodePen.
Chris: Interesting, right? If you put a private thing in a public collection, ooh, a little brain fart, huh? Hmm... What should we do?
Well, that's a product level choice, and our product level choice is when you share that collection with someone, the private items are not visible in it. They're filtered out.
Chris: That query that asks for the items has auth stuff happening behind the scenes to return only the right items. A little twist. If the collection is private, private items you put in the collection are visible.
Chris: That's logic. Somebody has to write that, and somebody has to test that too to make sure that it stays right over time.
Dave: Yeah. DALLE can't do that.
Chris: No. Certainly not. [Laughter]
Chris: We've also been investing in -- and just to twist this up a little bit -- is the things that you can generate. Let's say you have a table of data. Those tables are going to stabilize over time. You have a user's table, and it has all kinds of stuff on it: email address, a salted password. It's got your location, maybe your sign-up date, all kinds of stuff in it.
You can write code. Alex has done so now (that's very clever) that will look at a database table and generate a ton of this stuff. Not everything. Not the interesting logic. But the goal is anything that's unique logic to your app, you can still write. But anything that's rote, that's like, "How do I query for it?" there's probably eight ways that you could query for user stuff, "Give me a user by the ID. Give me multiple users by this input query. Write a mutation that updates a user." All that stuff, you shouldn't be writing that by hand - we've learned.
Chris: Write a generator that can generate all of that stuff and spit it out. There are third-party tools to do it. We didn't do that because we only ever write our own technology because we're crazy. [Laughter] Rote generators for all of this stuff is really cool now. You can see the two files sitting right next to each other. There's always a .gen.go file and a .go file, and the .gen one means, "Don't touch this. That was made by a computer for your benefit," and it has probably ten times as much code in it than the handwritten files do.
Chris: If there's a get pen by ID part of our API, that was not written by hand. That was written by a computer to say, "This is how you should respond to an API request like that." Very interesting.
Dave: Wow. You know it's funny. I watched a few videos on API design, and they were like, "Hey! Let's pretend we're interviewing for Netflix. How do we design an API?"
It's like, "Well, we got videos, so we're going to have a videos table with an ID and a file URL. Okay. Next, we've got users. They're going to have lists, watch lists, and watch lists have videos. I'm done. I invented Netflix again."
I love those videos, but I'm also just like, they don't get into that thing where it's like the private Pen is private, has privates -- or the private collection has privates. That's okay. But the public collection that has privates is not okay.
Then we had an issue, like, okay, teams have owners, right? Owners are users. Users have accounts, or users can delete their account, like, say, "I'm out of here. I don't want to use this app anymore." What if they're the owner of a team? [Laughter] Uh-oh.
Chris: Oh, all that stuff is in there. Yeah.
Dave: You know? Now you have all this stuff in the API. It's not as simple as just draw the tables in an ERD entity relationship diagram. There's weird logic.
Chris: Logic town.
Dave: Yeah. You're just deep into it.
Chris: Our files are in a folder called "Logic." [Laughter]
Dave: Yeah. Really?
Chris: It says user.logic.go.
Chris: And they're isolated there by way of strong convention. The way the API works is there's a folder full of .graphql files that explain the schema. They're literally in the GraphQL format. It says this is a typed Pen, or whatever. That's just GraphQL code that would be shared in any language.
Then we have a tool that looks at that schema and produces a resolver. A resolver is the very first thing that a piece of code that is hit when that schema is asked for, that query or mutation - essentially.
The resolver's job is to just really quickly be like, "Have I even been implemented or not?" If I'm not implemented, just bail - or whatever. Or maybe what's being returned is really simple. Like you have an API that just returns the name of the company. It just says, "Return Paravel," or something. [Laughter]
Dave: Yeah. Yeah.
Chris: it's just a string, so there's no logic there. It's just nothing. But if there's any logic at all, the resolver has to punt to a logic method. No resolvers have any logic at all. They either just return something simple or they ask the logic file for the information.
Chris: Then the logic file says, "Okay, well, if it's an authenticated user, you can tell them the true name of the company, which is 3 Pigs in a Trench Coat. Else, return Paravel," or something. [Laughter]
Dave: Right. Okay.
Chris: That's logic, so that has to stay there. Or if it has to ask the database -- oh, no. We keep the company name in the database. That has to make a query to do that. The logic is not allowed to do that either. It has to ask another file that is the logic method for about or whatever is the user. That's different.
Just by strong convention, we've separated all resolver code, all logic code, and all data store code. It's just been really nice and clear.
Dave: We're not quite there yet, but we have a pretty close setup. I made these, like, prepare data for update and prepare data for create.
Chris: Ooh, nice.
Dave: It's basically like I do all the data primping, all the logic kind of in a function that's outside of the setup. All that function is doing is, okay, save it but through the prepare data. Then that - whatever. It cleans it up, prunes all the garbage.
Dave: Sometimes your post data from JS app is not what the database wants or your database adapter wants.
Chris: Hmm... We have a meeting about that today at 1 o'clock.
Dave: Yeah, so we sent--
Chris: Rails was awesome at that, by the way.
Dave: Oh, Rails is--
Dave: Rails is always the standard, sort of, right? It's just like, "I don't know what that is. I don't care about an ID. I’m creating, so I'm just going to pop out the ID." But in my system, if you send an ID to the create function, it's like, "Dude! No!"
Chris: Yeah. "That is a protected field, bro."
Dave: "That's unique. Can't do it."
Chris: Yeah. [Laughter]
Dave: It's just like, "Okay. Could you just ignore it like Rails did?"
Chris: No. You've got to munge it first.
Dave: "I can actually output the form fields without you typing the type of form field. You just say 'field'."
Dave: Isn't that beautiful?
Chris: Yeah. Even its updates were efficient. If you send me 50 fields and I know that only 2 of them have changed, it will only send those 2, which makes overwriting sensitive information.
Dave: So great. Yeah.
One thing that I like is that you don't have to refresh the page. If you're hitting an API, you can leave the front end open and keep hitting save (or whatever button it is you're hitting). Because you've updated the back-end code, the back-end server has rebuilt. There's no need to command-R the fricken' page.
Dave: Wow. Okay. Wow.
Chris: I just like that about back-end work. It's fun.
Dave: When it's decoupled, right? When it's a decoupled app or whatever.
Chris: Yeah, right. It's hitting some URL of a server that's been rebuilt anyway, so it's fine. But where you dig out that information is kind of up to you. The console.log of Go is to user a logger package, probably, or write your own, which of course we have because we never use anything.
Dave: Sensing a trend.
Chris: There's a format package in Go, FMT, and you just say fmt.printline, and it'll print the line or whatever. That's what everybody uses. And it just goes to standard output in the log. But of course, so do database queries. Your logs, while you're browsing the app, are just flying by at 10,000 miles an hour, and I just saw a cool trick that somebody tweeted me after I was complaining about this that I thought I'd share on the show.
If you use iTerm -- a lot of people use iTerm on Macs. I think there's some muscle memory to it. I think a lot of people have probably switched to just using the console in VS Code because it's right there.
Chris: But weirdly, a lot of people use iTerm 2, still, because it just had so many advantages over the built-in console when it first came out that there's a lot of muscle memory for it. It had tabs before the native one had tabs, and stuff like that, I think.
Dave: I have it. Yeah, and even after switching back from Windows. It was one of the first things I installed because I opened up the regular terminal and was like, "That's not the right one." But I do use VS Code mostly.
Chris: Yeah. Me too. Especially for tests and stuff. Anyway, everything is complicated. I don't know.
You can run ours on any terminal, our dev environment, but I just happen to use iTerm, and I know Alex does too. It's just when you pair program, it's kind of nice when you're using the same crap so that you can talk a little more comfortable.
Anyway, it has this feature that I would never dream on finding, like finding it was difficult to begin with in preferences. You open preferences. You go under profiles. Go under your profile. Go under the advanced tab, which is nine tabs over. Then in that, there are five things.
One of them is called triggers. Very interesting. Open up triggers and you can make triggers.
What they do is they just watch standard out on your logs, and you can put in a regular expression of something to watch for. Now, our logger package, we prefix all the logs with, like, I'm about to log something. It says info in square brackets, so I write a regular expression for that piece of output.
Then it has an action, and the actions is where things get interesting. You can make your computer beep. You can highlight it specially with special highlighting.
Chris: There's literally 25 things you can do when the regular expression matches, which is so rad, I think.
Chris: You can run an Apple script - whatever. But the one I did was just capture output, and capture output is really simple. You open this little drawer.
Chris: They call it a toolbelt, I think, in iTerm. Say, "Show toolbelt," and then show your captured output in the toolbelt. And then any time it matches that RegEx, it just shows a little entry in the toolbelt.
If you're console.logging, essentially, which would work too if you're in a Node app--
Chris: But I'm in Go or in Ruby it'd be puts or use awesome print or something.
Chris: It goes to standard out, and you can just watch, watch for any hand-logged things.
Dave: Some kind of emoji or something, and just be like--
Chris: Yeah. Exactly.
Dave: Now it all just shows up. Wow.
Chris: Isn't that nice?
Dave: I'm having that log problem, too. I've scoped it to a certain server, but yeah. My database is logging every time it tries to connect to itself, like its stay alive function.
Chris: Right. Mm-hmm.
Dave: It's four logs every four seconds - or something like that.
Dave: I'm just like, "Can I turn this off?" The answer is no right now. [Laughter]
It was just like if my logs are just garbage now, but it would be cool if I had, like, "Hey, found an actual problem." Then I go to Sentry. I have Sentry hooked up. Sentry is great.
Chris: Right. Same.
Dave: But Sentry, too, is sort of like, "Uh, line 92 of error JS in file XRB93#59000."
Dave: "Problem, guy." You know?
Chris: [Laughter] Right.
Dave: I'm like, "Of course. Error. Just having trouble today." You know?
Chris: It's a lot. Yeah.
Dave: And I'm ... Webpack, but I'm trying to be nice.
Chris: You can see those errors on the front-end, too. I don't know. I just find back-end error reporting in any of these tools like Sentry is way more useful.
Dave: Right. Yeah.
Well, cool. We should probably wrap it up. That was a good ol' dive in the back end, Chris.
Chris: That's right.
Dave: That was interesting. I'm hoping one day to move out of servers. That's my goal. I'm going to buy my way out of that situation.
Dave: Anyway, 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, @ShopTalkShow, for eight, six tweets a month. You know how it goes.
Dave: It keeps going down. Join us in the D-d-d-d-discord. That's where we're at mostly. Patreon.com/shoptalkshow. Chris, do you got anything else you'd like to say?
Chris: console.log ShopTalkShow.com.
Dave: Error on line nine.