The Salesforce Developers website will undergo maintenance on May 29, 2024 from 3:00 a.m. UTC to 10:00 a.m. UTC. The maintenance process may affect the availability of our documentation. Please plan accordingly.

Kevin Poorman is a Salesforce Architect over at Chief. He is joining us in this episode to talk about one of his newest projects, Apex Kit. Apex Kit is a library of tools that all help developers do repeated actions accurately and securely.

In our conversation, Kevin and I talk about his backstory and some of his career history. We also dive deeper into Apex Kit and get a full understanding of it. Enjoy this intriguing conversation with Kevin Poorman!

Show Highlights:

  • Where the idea for Apex Kit came from.
  • How Apex Kit works.
  • The connection between Apex Recipes and Apex Kit.
  • What promises in code are.
  • How promises get built into Apex.
  • What polyfills are and how they work within Apex Kit.
  • The function of Ouroboros in Apex Kit.
  • The difference between a ULID and a UUID and a use case for a ULID.

Links:

Episode Transcript

kevin poorman:
I remember my dad showing me gameplay of a video game on his Apple IIe. He had a Star Trek game.

josh birk:
That is Kevin Poorman, a Salesforce architect over at Chief. I’m Josh Birk, your host of the Salesforce Developer Podcast. And here in the podcast, you’ll hear stories and insights from developers, for developers. Today, we bring back Kevin into the studio to talk about one of his projects, Apex Kit, which is kind of a highly opinionated library, shall we say, for a lot of the stuff that you need to do with Apex. But we’re going to continue on right there where we left off with his early years about that Apple IIe game.

kevin poorman:
… and it this like… It was a little bit, you sunk my battleship, where there was a field of green text on the black screen and you had little K’s for Klingon ships and you had the E for the Enterprise and you had to navigate around the screen and find the Klingons. And then… Well, in my case, I die quite a lot.

josh birk:
I vaguely remember that. Yeah, it was like a combination of Minesweeper and Battleship or something like that.

kevin poorman:
Yeah.

josh birk:
Yeah, yeah. Nice. Was computing something you always wanted to get into?

kevin poorman:
No, no. When I was a kid, I did dance.

josh birk:
Okay.

kevin poorman:
I was a ballet and jazz dancer, and then I shattered my left hip when I was 14. And turns out in Kansas, even if you’re in the hospital, the state says you still have to go to school. And so the hospital room school was to go down the hall in my wheelchair and futz around on an Apple Iie, and so I started learning how to write basic… Apple basic.

josh birk:
Got you. When did you first get introduced to Salesforce?

kevin poorman:
Oh, let’s see, probably 2000… December of 2008. January 2009. Somewhere there. I was working at a email marketing company… I’m sorry. And they decided that they needed to move away from sugar. And earlier that week, we had run out of space on the database server and the DBA had just deleted all the attachments.

josh birk:
Oh.

kevin poorman:
Sugar. And then they were like, maybe we should do something in the cloud. And so yeah, we switched to Salesforce in six weeks, I think. And I was part of the team that helped do that.

josh birk:
I have nothing against Sugar, but I will use an old joke. A friend of mine who is a sales guy at Model Metrics used to call Sugar one of the best pre-sales tools he ever had. So yeah, I don’t think you’re alone in that particular transition. How would you describe your current job?

kevin poorman:
My current job… I’m a Salesforce architect/staff level engineer, wrangling all sorts of fun things here at Chief.

josh birk:
How many hats do you think you have right now?

kevin poorman:
More than I have heads. I’ll put it that way. I haven’t even… I should stop and think about that and count them up. Today, I’ve been playing release manager.

josh birk:
Nice.

kevin poorman:
And yesterday was all CI stuff.

josh birk:
Yeah. Yeah. Nice. Now in between last time we spoke and your current role, I just noticed this on LinkedIn, so I have to ask, you worked on a, and I think I’m quoting here, a multilingual weight calculator for FedEx?

kevin poorman:
Yeah. Yeah. So the timing on that’s off. I did that a long time ago.

josh birk:
Oh, okay.

kevin poorman:
When you ship something, there’s the idea you have dimensional weight and dimensional weight doesn’t make any sense as a sentence, but the idea is-

josh birk:
It sounds cool though.

kevin poorman:
Yeah, the idea is that sometimes the dimensions of the object you’re shipping are more important than the weight of the item you’re shipping. And so they take the height, width, and depth of the packaged box and they come… There’s a calculation to determine its dimensional weight. It’s an algorithm. I wrote a bit of code to do that on… It was I18, and for all of the various German subsidiaries, or not German subsidiaries, EU subsidiaries… EU localities I think is the right way to say it.

josh birk:
Yeah, nice.

kevin poorman:
That was long time ago.

josh birk:
Got you. Well, more relevant. You’ve also released Apex Kit, correct? That’s a singular? Apex Kit.

kevin poorman:
Yeah, Apex Kit.

josh birk:
And how does this involve woodworking?

kevin poorman:
I feel like during the pandemic, everyone either adopted a pet or picked up a new hobby.
I picked up woodworking. My quasi therapist was like, you need a hobby that will force you to slow down. And the only way I can think that would cause… The only thing that she said she could think that would cause Kevin to slow down was something that might cost me my fingers. And so her suggestion was woodworking. And I’ve always enjoyed woodworking and that sort of stuff. So I picked up woodworking and I get to use all sorts of saws. And if you’ve never done woodworking, you may not know this, but woodworking equipment is, it’s on the expensive side. It’s not like, oh, I’m going to pick up a new hobby type level thing. So I have a lot of really old vintage equipment, which is great because it’s indestructible [inaudible 00:05:13] me. It also has zero safety features.

josh birk:
Nice, okay.

kevin poorman:
So I definitely have to slow down and think through things.

josh birk:
Got you.

kevin poorman:
But as I was picking up woodworking, and I’m reading and I’m watching YouTube videos and I’m talking to other people, and I joined Central Indiana Woodworkers Guild, which is a bunch of people that like to make things out of wood.

josh birk:
Nice.

kevin poorman:
And I joined them and I’m learning all this stuff from them. I learned that most of the time… You think about a hobby, like, oh, I’m going to go paint something. And then you sit down and you start painting.

josh birk:
Right.

kevin poorman:
Or you sit down and you go, I’m going to learn to play the piano. And so you sit down and you start hitting keys. In woodworking, it’s not that. Woodworking, you end up making things to make the thing that you want to make, which doesn’t make a whole lot of sense. But a lot of woodworking requires precise angles and accurate cuts. And the only way to get, for instance, four table legs that are exactly the same size is to make a jig. And the idea of a jig is that you have something that you’ve built. Sometimes you can buy them, but most of the time you build them. And these jigs help you make repeatable, accurate, precise cuts. Imagine something that you can put the piece of wood into, and it will always cut that piece of wood at 31 and 16 or 11/16th inches long or whatever the measure was.
And as I was… I’m building these jigs to do different things. And I remember, I was sitting there. I was building a cross-cut sled with a stop block. And which is a very fancy way of saying I wanted to be able to cut something at 31 inches and 11/16ths, but do it 500 times perfectly accurately, and I build this jig, and I think, so much of what I do in software could really benefit from this same idea. So I started putting together a list in my head of jigs, software jigs, which are a tool or a framework that helps you do something repeatably and accurately, and in software’s case, securely and safely without accidentally… These are things that everyone has to do sooner or later, but it’s really easy to get wrong.

josh birk:
Right.

kevin poorman:
So we have various jigs in here that help you do different things, but they help you do it safely and securely. And because you can just pick them up and use them, you don’t have to reinvent the wheel.

josh birk:
So first of all, I love that analogy because it’s like it’s not wood carving. You’re not taking a block of wood and then carving away everything that doesn’t look like an elephant. You’re left with an elephant. It’s like, a table has four legs. You have to figure out how to build the one leg, do that three times, and then figure out how to put the top on and make sure everything’s fitting together. It also sounds like a slightly more abstracted way of thinking about a utility lib or a framework. How does the interoperability work with this library? Are they independent structures? Do they work with each other? A little bit of both?

kevin poorman:
A little bit of both.

josh birk:
Okay.

kevin poorman:
So there’s different pieces to it. And again, the idea is that they’re different jigs in your shop to use. So for instance, there’s a query library, and that query library also uses a safety and security library called Safely. And you can use Safely independently of the query library, but if you adopt the query library, you automatically get to use Safely.

josh birk:
Got you. Because Safely works at the DML level. So then if you’re using the query language, it’s pulling in Safely so that it knows that it’s doing the DMLs correctly.

kevin poorman:
And then, this is a great example. Safely is a jig to help you do any kind of DML in a way that prevents CRUD and FLS leaking.

josh birk:
Got it.

kevin poorman:
Which is to say it’s, I guess in a more common way of saying, it’s going to enforce CRUD and FLS on all the DML you do through Safely.

josh birk:
Got it. What’s it like to have things… Do you find yourself not competing, but catching up with security updates as they come through Apex when it comes to things like user mode and stuff like that?

kevin poorman:
Yeah, so that’s a great question. It’s currently not updated to use user mode. That’s in the works. So the way it’s currently written, that particular instance uses technology, the security decision object that goes back probably two years at this point. But when we get into user mode stuff that’s even more precise, and so that’s coming, and yeah, there is a sense in which… There’s a sense in which jigs are never done. You’re always going to be adjusting them. And whether that’s because there’s something new or because when I make a jig, that jig fits my particular saw. I can’t just let my neighbor borrow that because he has a different kind of saw. It won’t fit. Keeping them up to date is a little bit of a… It’s a challenge, but it’s also the fun bit because it keeps me up to date on all the good stuff.

josh birk:
And I think it’s a challenge that’s well known to Apex developers. Three releases a year. We’re always trying to keep up. I think back in my Model Metrics day, I was always like, if you’re using the same code you’re doing three months ago, you’re probably doing it wrong. Constantly go back and reevaluate because what you’re doing in 10 lines might be just one these days.

kevin poorman:
Well, I’m going to challenge you on that because the whole idea of something like Safely is that it’s that jig. Then if you’ve written code to utilize Safely, if I go in an update Safely to use user mode-

josh birk:
You’re not breaking-

kevin poorman:
… that API hasn’t changed.

josh birk:
Got you. Yeah, nice.

kevin poorman:
I’ve made it better. You reap the benefits of that, but you don’t have to necessarily have to update your code.

josh birk:
Got it. Got it. No, good point. Before we get into more of the specifics, I kind of want to call out that you also back at Salesforce released a project called Apex Recipes. Now what’s the connection and the distinction between that project and this one because it feels very similar and yet very different at the same time.

kevin poorman:
So Apex Recipes started off life as any of the recipes projects do. An example code that teaches you how to do things and the code you write to teach someone how to do something is vastly different than the code you write to actually do something in production. So there are parts of Apex recipes that do not necessarily reflect the best security practices in terms of how to query things or with security enforced, that sort of thing. But they’re also there to illustrate what you can do, not necessarily what you should do, because sometimes you have to know what you can do before you really understand what you should do. So Apex Recipes is sort of… The Apex Kit kind of grew out of Apex Recipes. It’s the spit and polish on the learning repo to make something that you could actually use in production.

josh birk:
Got it. Well, and if I remember several discussions back in the early planning phases of Apex Recipes, the goal is to be slightly opinionated. Don’t be opinionated until you kind of have to be opinionated and then offer that in because it’s going to make for more complete code. Is it fair to say that Apex Recipes is the lightly opinionated, but Apex Kit is very strongly opinionated. This is Kevin Poorman’s… This is how you believe this should be done and put into production.

kevin poorman:
So about five years ago, there’s this guy named David Heinemeier Hansson. He’s the progenitor of Rails, the framework for Ruby. And he gave a Ruby or Rails comp keynote where he talked about how Rails is Omakase. Omakase is a Japanese word that means… I don’t really know what it means, but the connotation translation is that you trust the author or in the case of omakase, it actually comes out of sushi culture. And if you walk into a sushi restaurant in Japan and you say, omakase to the sushi chef, you’re making sort of a [inaudible 00:13:15] bargain or social contract with the sushi chef that you trust them to give you their very best.
And you’re not going to worry about ordering anything. They’re just going to bring your food until they have to wheel you out. And David’s idea there is that Rails is omakase, meaning that you have to trust the Rails core team and developers that they’re going to help you build your stuff correctly with the idea of convention over configuration. That’s the whole Rails magic. So I like to say that Apex Kit is omakase. You don’t have to eat everything that’s delivered to you. So if you only want to use Safely by all means, but the whole Apex Kit itself is very opinionated as to how you should do things.

josh birk:
Go you. Now digging into some of the details, I want to talk about one that I know you’ve worked on actually for some time, so it’s not surprising to see it in this library. Apex promises to level set for the novices. What exactly are… What’s a promise structure in code?

kevin poorman:
So promises, as far as I’m aware, the whole idea of a promise originated in JavaScript.

josh birk:
I think that’s right. That’s my belief as well. I’ll share that at least.

kevin poorman:
So at least that’s where I came across it. I’ll put it that way. So promises in JavaScript are a data structure and/or a technique that allows you to call a method that returns the promise of an eventual value, which is a $10 way of saying, it’s going to do something asynchronously and return it to you at a future date. In the JavaScript world, this has largely been replaced, or not replaced with, it’s been enhanced to do async await. So if you’re familiar with async await, async await in JavaScript works by creating a promise and returning the promise. And so the idea here is that with a promise structure, you’re going to go run… You’re going to say, hey, I need to go run this work. It’s going to be asynchronous. I don’t know when it’s going to complete. And then it allows you to attach work to be done when that work completes. So I can say, go do A, and whenever it’s finished, go do B.

josh birk:
And coming from a pre-promise world, I think people should appreciate what that’s replacing, which was essentially a series of functions with inputs waiting on each other sort of thing, which worked. And I’m going to dig in this a little bit here in a second, and I’m kind of guessing the behind the scenes functionality may not even be all that different, but it’s really hard to read. You almost had need to know the map to know from this function we’re going to this function, then from this function we’re going to this function. And God forbid if there’s an if-else in there somewhere. So what’s it like to port something like that into Apex? Because my first thought would be that’s a very… It’s almost like a system level functionality, but what was the reference that you’re using to build something like that [inaudible 00:16:09] into Apex?

kevin poorman:
So I thought about it long and hard, and the original need for this arose… I was working with a nonprofit to help them do some geospatial calculations in Apex, and that involved callouts to various APIs. And at the time you, could only make, I think, 10 callouts per transaction. HTTP callouts. And so I had to find a way to break these up because these were complex streams of API queries. And I started looking at how promises worked in the JavaScript world. And at the time, this is so far back, the promises weren’t an official part of the JavaScript language. They were implemented in sort of NPM libraries. And the one I looked at was, I think it was called Bluebird.

josh birk:
Oh, yeah. Bluebird, okay.

kevin poorman:
And I just started looking at how they did it. And it’s hard because JavaScript and Apex are radically different languages, and I don’t have the system level access that the JavaScript does. But I looked at… Fundamentally, what I needed to be able to do was run some asynchronous code. And Apex at the time had at future methods, and it also had… This is right after queueables was introduced.

josh birk:
Right.

kevin poorman:
And so I’m like, okay, this brand new thing called queueables, and I had to keep track of a list of queueables because… Oh, it almost goes without saying that if you’re using a promise, you have multiple things in sort of a promise chain. You’re going to do A and then B, and then C and then D. And I wanted to add onto to that some things that Bluebird had, which was not only to run asynchronous work and to keep track of that asynchronous work, but also to have air control.

josh birk:
Got it.

kevin poorman:
So I wanted to be able to say, oh, this failed. What do we do now? And so I looked at how could I do those two things in Apex? And what came to mind was I could use queueables to do the asynchronous work and I could… Because queueables can queue one more queueables. I could write the code in such a way that I could pass a list of queueables objects down the chain so that when the next queueables started up, it just needed to take the queueables off the list and execute that. What the promise framework in JavaScript looks like is… Excuse me, in Apex, it’s kind of tail recursion. Every time the queueable ends, it says, hey, do I have any more in the list? And then it executes the next queueable.

josh birk:
Gotcha.

kevin poorman:
So two years ago, three years ago, they came out with finalizers and it’s been rewritten to use finalizers, so it’s even a little bit more composable.

josh birk:
Got it. A couple of different ways I can follow up on that one. I’m going to go in this direction. I thought this was an interesting thing to put into an opinionated library like this, that what you’re describing, and I’m going to be a little recursive here, but what you’re describing is kind of like a polyfill, right? Would you define… So… Well, let me just throw that back at you. How would you define a polyfill?

kevin poorman:
So I’m going to answer that question, but first I want to apologize to Daniel and Chris because I’m about to poke him in the eye. And a polyfill to me is functions that should be written and supported and maintained by Salesforce as part of the Apex language, but are not.

josh birk:
Right. Well, I mean, they only have so much time on the planet. Their job right now is figuring out how to bridge that gap. This gap… So one of the reasons I really wanted to focus on this was in my conversation with Greg Whitworth. We go into great length about how the concept of a polyfill is basically something that should eventually become obsolete because it is what you’re describing. It’s something… It’s like saying, hey, I’ve seen your platform. I really think it should have this. Kind of like Bluebird, it doesn’t. So we’re going to write that until you catch up with it and then we can throw the whole thing out. So I don’t think any… [inaudible 00:20:16]. That might be more of a poke in the shoulder than the eyeball, but what-

kevin poorman:
No, that’s fair.

josh birk:
How does that work within Apex Kit? What does Apex Kit do to help me create a shim like that?

kevin poorman:
I’m not sure I followed your question.

josh birk:
What portion of polyfills are supported by Apex Kit? Maybe a different way of putting it.

kevin poorman:
There’s an entire polyfills class in Apex Kit.

josh birk:
Got it.

kevin poorman:
It contains… I was talking at a user group meeting last night and I talked about how whenever you go through the process of splitting your code base into various packages, inevitably you end up with the package titled, everything we don’t know where else to put.

josh birk:
You start with everything, the miscellaneous drawer, and then the miscellaneous drawers get smaller, but it’s still there.

kevin poorman:
Right, it’s still there. No one’s going to get it. They get rid of it. And so I have a polyfills class in Apex Kit and it contains things that… It’s a little bit of, I don’t know where else to put it. And also it’s things that really should exist at the Apex level rather than something that is coded. And it’s everything from give me an… Here, take an instance and give back its class name.

josh birk:
Got it.

kevin poorman:
To give me the type based on a class name. And that sort of stuff can be done in Apex. It’s just not a one-liner.

josh birk:
Right. Right. And it’s also the kind of stuff that is handy to know isn’t. That class might just be a handy reference guy to be like, you don’t have to spend three hours digging through the documentation to figure out what the class name is because the class name doesn’t exist. Here’s one for you.

kevin poorman:
I have a need to be able to generate a stack trace and not on an exception. So there’s an exception in here called guaranteed not to exist exception. And it’s an exception that can only ever be thrown by the abil… When you ask for a stack trace.

josh birk:
Got it.

kevin poorman:
And so you can get a stack trace there.

josh birk:
Nice, nice. Now, changing course a little bit back to that idea of a list of queueable objects that kind of get ticked off because I believe this is similar but different. Tell me a little bit about how ouroboros works. And I think I’m saying that name right? Is that right? Ouroboros?

kevin poorman:
Yeah. Can I start off with the premise that naming things is hard?

josh birk:
Naming things is hard. It’s true.

kevin poorman:
Ouroboros is… It’s a famous symbol and I don’t really know where it’s from, but if you were to Google ouroboros, you’ll see this picture and it’s a picture of a snake eating its tail. And the idea is depending on which… Because it’s from multiple cultures, and if you look around, it’s the idea of never ending or rebirth or the whole idea that this thing you can’t find at beginning or an end. Ouroboros is a riff on promises, but instead of having a finite set of elements in the list, ouroboros will reinqueue itself. And so these both promises and ouroboro are implemented as abstract classes. So you’re going to write your own ouroboros implementing class, and it’s going to be reinqueued to do some work. And when in that work is done asynchronously, it’ll evaluate whether or not it needs to reinqueue itself. And if it needs to, it’ll reinqueue itself. And the idea here is this is the answer to how do you eat an elephant and you do it one bite at a time.

josh birk:
Got it.

kevin poorman:
Right. So if you have to, and this came up when I was helping somebody. They wanted to write something… They needed to do something to iterate it over 3 million contacts and you could use a batch job, but what are some other options? And we came up with this where we’re going to take a chunk of 200 contacts and do something to them and then say, okay, we’re done. And then we’re going to say, oh, we’re not done. We still have 2 million whatever to go through and reinqueue itself to do it.

josh birk:
What does that look like in production? Two questions comes to mind with that. One is, how long does it take to eat that particular elephant? And then the second one is, what happens when something goes wrong on contact 1,300,000? It’s like halfway between a batch of that size. What happens if something throws a wrench in the system?

kevin poorman:
Well, because they’re all done in batches as discreet transactions, if an exception occurs… It depends on how you… Well, it depends on how you’ve written it to start with. But in theory, if you’ve written it perfectly badly, it wouldn’t just destroy that transaction and it could get kind of caught in the wayside, so there’s a sense in which this is a jig that is… I should probably polish that jig a little bit, now that you mentioned it. But in practice… So this was written with a very specific use case in mind where they needed to deal with… So if you’re not familiar with the concept of data skew. Data skew is where you have a relatively small group of parent objects with a outsized number of child objects associated.

josh birk:
Okay.

kevin poorman:
So imagine if you’ve got 10 accounts, but you’ve got 3 million contacts.

josh birk:
Got it.

kevin poorman:
And we need to be able to update those contacts or those accounts without hitting data skew limits in the lovely unable to lock row for update error. And so the idea here is you consider very small size for your execution context and bite through them and it’s going to take a long time. But this allows you to correct that data skew so you can move away from 10 accounts owning 3 million contacts to a more balanced one and a half million accounts with 3 million contacts.

josh birk:
Got it.

kevin poorman:
That’s why this was written.

josh birk:
And so you’re kind of trading time and raw performance power for flexibility and the ability to basically say, I don’t really care how large this data set is. It’s going to get done whenever it gets done.

kevin poorman:
Exactly, exactly. And the other use case that exists for it is back in the… If you remember back in the DOS days, you had terminal stay resonant.

josh birk:
Oh, god yes.

kevin poorman:
… programs, and so you can write one of these. It’ll sit there and just keep itself in queue to keep running, waiting for something that needs to do in the background.

josh birk:
And when we describe it as slow, it’s slow compared to other things, but how long does it take to get through 3 million records?

kevin poorman:
Oh, I think it took like six days.

josh birk:
Which is not, press it and get it done, but if you’re not spending any time in those six days and it just gets done in the next six days, then that’s doing pretty darn good.

kevin poorman:
And if you’ve got a problem, it’s like data skew, where you can’t just go and… I mean, your other option is to do an extract update in Excel and re-upload.

josh birk:
Right.

kevin poorman:
Which of those do you really want to do? Which one’s going to be safer or less risky?

josh birk:
My brain can wrap around this a lot easier because I’m not worrying about the 3 million. I’m worried about the code that I want to do per 200 or something like that. And so my neurodivergent brain doesn’t want to think about how to handle data science that much, but I do want to think about the functionality that I want to apply against it, so I like the trade-off. Speaking of strange words, what’s Quidity?

kevin poorman:
That one’s not on me.

josh birk:
That one’s not on you.

kevin poorman:
Quidity came out of the minds of the Apex team at Salesforce. As I understand it, Quidity is a Sanskrit word that means the essence of the thing.
And Quidity is a enum in Apex on the request object. So given any Apex transaction, you can ask for the request and then you can ask it for it’s quidity and it’ll tell you the execution context of that transaction. And there’s probably 2025 quidities in the enum and they range from are enabled to testing to testing in parallel or doing testing during deployment. And so you can think of all the various possible ways that Apex could be executed, you’re going to see all those reflected in Quidity. So there’s execute anonymous or custom apex endpoints, all this stuff.

josh birk:
Got it. And this jig is a wrapper class around that?

kevin poorman:
Yeah. It’s a way of… So you can do a lot with Quidity, but one of the things that I think is most useful for is to use Quidity as a gating function to prevent code from being run that you know is potentially unsafe if there’s user input.

josh birk:
Got it.

kevin poorman:
So imagine if you use Quidity guard to say, this can only run in triggers or this can only run in an AURA enabled or this can’t run an AURA enabled, then you can turn around and you can say, listen, there’s no way for [inaudible 00:29:04] injection to occur here because I’m not allowing this to run a Quidity where there’s any user interaction.

josh birk:
Got it. Got it. Interesting. Now I’m going to confess until I started reviewing your repo again, I had not heard of the concept of ULID. What is a ULID and how does it compare to our old friend a UUID?

kevin poorman:
So the ULID has a somewhat more modern take on a universally unique identifier. Okay. So it’s like a UUID in that it’s an identifier and that it is universally unique. It’s different from a UUID in its format. And the big difference is that it is lexigraphically sortable, which is, again, it’s a $10 word for the idea that you can alphabetize it.

josh birk:
Got you.. My brain was catching up on that.

kevin poorman:
Right. So you can generate an ULID and in fact there’s an Apex Kit method for generating a UUID and that’s going to give you a perfectly random string. Whereas a ULID is going to give you a random string that starts with an encoded date and because of that, you know what order they were created in, so you’ll never get two ULIDs that are the same, but as you create new ones, they will auto increment up for lack of a better term.

josh birk:
Got it. So it’s almost like the concept of a primary foreign key and a UUID together in… What’s a solid use case for that? Where is ULID going to kind of save your bacon?

kevin poorman:
So let me back up. There’s a new version of UUID, the classic version, the one that everyone sort of uses now is UUID V3. UUID V4 is lexigraphically sortable, but it’s also not… Doesn’t have anywhere near the adoption of a UUID. The idea behind a ULID is if you want to be able to generate a unique ID to share between systems, but you also want to be able to sort the sequence of those IDs or events that are tied to those IDs independent of the other system, you can use this to say, okay, I know that this one happened before this one.

josh birk:
Got you. Without having to do checking for modified data or create a data or anything like that.

kevin poorman:
And one of the things that I find oddly strange about the platform is that there’s not an ID service users or the developers can tap into and say, just give me an ID. So this serves that need for… So we can say, hey, I need an ID. It’s got to be URL safe. It’s got to be sortable and it’s got to be guaranteed unique here so that I can share this and this data between multiple external systems.

josh birk:
Got it. And have it sorted the same way.

kevin poorman:
And have it sorted the same way.

josh birk:
Got it.

kevin poorman:
Yeah.

josh birk:
Now in a 30 minute, 30 to 40 minute interview, I don’t want to diminish the scope of Apex Kit. I was kind of digging into some of the stuff that I think was particularly nerdy and cool. But you also have logging jigs. You have a test factory jig. You’ve got a mock jig. You have the boilerplate stuff that people would want to work with as well. Is there any one of those that you want to give a shout-out to?

kevin poorman:
Two that come to mind. One is feature flags.

josh birk:
Okay.

kevin poorman:
So I’m a huge fan of feature flags if you’ve ever seen and had for LaunchDarkly or some of these other companies that do it. There’s also an open source… I think it’s an Apache project. I don’t remember what it’s called, but the idea is behind a feature flag is that you create this thing that says only if this thing is true or a user has this flag assigned to it, can they access this functionality.

josh birk:
Okay.

kevin poorman:
And the idea here is, do you want to be able to turn something on or off at three levels? You want to be able to turn it off universally for the whole org. You want to be able to turn it on or off for a particular user and you want to be able to turn it on or off for a particular permission or permission set.

josh birk:
Got it.

kevin poorman:
Right? And the idea here is you can use this feature flag jig in order to have your code say, listen, I’ve deployed a feature, but I don’t want to turn it on until Tuesday.

josh birk:
Got it.

kevin poorman:
Or I want to disable this trigger, so we’re going to disable the feature flag for that trigger.

josh birk:
Got it. Nice. And this feels particularly relevant for a platform like Salesforce where you have stuff in production that we might want to have to turn off so that it’s not breaking everything else, but also we just have such a myriad of user permissions and org permissions and enterprise additions and all those kind of… What can you do changes from one org shape to another, so instead of writing one really clunky if statement, you can just use this.

kevin poorman:
And feature flags is the… Feature flag jig is actually written to also work with the conditional visibility within flexipages.

josh birk:
Huh, nice.

kevin poorman:
So you pull that in there and turn on or off features that way as well.

josh birk:
Got it. So not just a grand don’t do this class thing, but possibly even just don’t show this portion of a lightning web component or something.

kevin poorman:
Exactly. Exactly.

josh birk:
Nice. What was the second one?

kevin poorman:
The other one that I’m a big fan of is the REST library.

josh birk:
Nice.

kevin poorman:
So one of the things that almost every org has somewhere deep buried in its bowels is the call-out to an API.

josh birk:
Yep.

kevin poorman:
And when I first started doing this, one of the things I loved about Salesforce was you can make a HTTP call-out in five lines of code. And the older I get, the more I realize that I really don’t want to use just five lines of code to make [inaudible 00:34:46] call-out.

josh birk:
Exactly.

kevin poorman:
And the other thing I picked up on over the years was that if you are interacting with an entire API, you don’t want just write a bunch of methods to make one call. You want to have abstract away some of the boilerplate. You’re always going to set the same headers. You’re going to worry about authentication, all that sort of stuff you want at a different level than, okay, go hit the endpoint A.
And so REST library has… It has a helper class, a syntactic Sugar class that’s going to get [inaudible 00:35:17] say, okay, create this and or go make this post-call and it’ll extract all the regular stuff around a post-call for you. Take the body, take the headers, whatever, do it for you. But it also has the ability for you to write a custom class that extends the REST library for a particular API. And that allows you to set the named credential for everything in that class. The headers for everything in that class. And then your class can be like, okay, I want go get the ID or go get the cases or whatever it is that your external API you need to do rather than go make a post call to get this. And so your API can be more descriptive and more, I don’t know, elegant. I’m going to say elegant. I mean, this is my opinion on it, so it’s more elegant.

josh birk:
And that’s our show. Now before we go, knowing that Kevin is a fan of woodworking, I was asking him what’s he working on?

kevin poorman:
Yeah, so I’ve been working in the wood shop on Christmas presents for Christmas 22.

josh birk:
Oh.

kevin poorman:
Which is [inaudible 00:36:23] a little behind. I’ve been making salt cellars.

josh birk:
Nice.

kevin poorman:
So if you’re a foodie, a salt cellar is a little, in this case, wood dish with a lid that swings side to side that holds salt. And you put it next to your stove and then you can cover it so that your cat doesn’t sit there and lick your salt all day. But then when you’re cooking, you can just swing it open, grab a pinch of salt and drop it in your pan. I’m making some of those for Christmas gifts.

josh birk:
Got you. I love it. I feel like that you just maybe also told us the inspiration for the adventures. I want to thank Kevin for the great conversation and information. As always, I want to thank you for listening now. If you want to learn more about this show, head on over to developer.salesforce.com/podcast where you can hear old episodes, see the show notes, and have links to your favorite podcast service. Thanks again everybody, and I’ll talk to you next week.

Get notified of new episodes with the new Salesforce Developers Slack app.