Shownotes
Our focus in today's episode is more on the technical side of things and we get right into the weeds on the subject of how to continue your development work when you do not have all the API information you need. We speak about a bunch of options at your disposal, some of which we have tried and some that we have merely heard of, but whichever route you choose, this is definitely something you need to be able to do! Tuning in, you will hear about some recommended resources and tools for the processes of creating mock data and fake responses, and how to approach the data structure and model for the best results. We also get into some thoughts on the responsibilities related to APIs and why considering the different kinds of brains and machines that might be interpreting the data can help us format it most effectively. To finish off, we list a few of our wins and losses in the domain, before getting into this week's fun picks, including a novel, a TV show, a Japanese word game and more!
Key Points From This Episode:
- Our past strategies to deal with an endpoint that is not yet ready to integrate with.
- The packages, across different languages that can help in the process.
- More online resources for finding necessary responses and elusive information.
- The value of creating fake responses for a working API.
- Approaches to data and making it readable for different types of people and machines.
- Data structure, sources of truth, and defining the data model.
- Whose responsibility is it to maintain APIs?
- Jumping off points for learning more about mocking data and playing with APIs.
- Mistakes and successes working with mock data and APIs!
- This week's picks: books, Japanese crosswords, cookies, and Superstore!
Tweetables:
“Today, we're talking about what to do when the API endpoint that you need to integrate with isn't ready yet, but you need to still continue development.” — Ari [0:00:21]
“Sometimes you need to actually be able to figure out the integration part of the API before the API is ready.” — Ari [0:06:16]
“If you're wanting to be able to run tests quickly, having to run your tests against an actual API, that can take a while.” — Alex [0:10:07]
“I do you feel like data transformation is one of the most painful parts of dealing with APIs, especially when the API is not in place.” — Tessa [0:12:40]
Links Mentioned in Today’s Episode:
- Hypothesis
- Mockoon
- Httpbin
- Mock service worker
- RedwoodJS
- OpenAPI spec
- Swagger
- https://github.com/Surnet/swagger-jsdoc
- Cypress Intercept
- Mock API Server Online Testing & API Mocking Guide, Stoplight
- Setting up mock servers, Postman
- Mocking by API, Postman
- API Mocking: Best Practices & Tips for Getting Started, SoapUI
- Amina’s episode
This weeks picks:
- Alex
- The Gilded Ones, Namina Forna
- Ari
- Superstore, NBC (television show)
- Tessa
- J-crosswords, renshuu (Android, iOS)
- Trader Joe’s Chocolate Chip Cookies
- Review: Sweet on Trader Joe’s: Chocolate Chip Cookies, Bake at 350
Transcript
[INTRO]
[00:00:10] AC: Hey, everybody. Welcome to Enjoy the Vue. I am Ari. Today on our panel, we have Alex.
[00:00:16] AR: Hello.
[00:00:17] AC: And Tessa.
[00:00:19] T: Hi.
[00:00:21] AC: Today, we're talking about what to do when, let's say, the API endpoint that you need to integrate with isn't ready yet, but you need to still continue development. What are our options there? Do you just make a file and then import that in? Do you just literally copy and paste it into the data and your components? I've done lots of different things.
[00:00:48] AR: I mean, the obvious easiest answer here is that you, in plain text, paste your credentials into a test file, and then make the API calls live as you need to. Then you just have to keep updating that test file with the new credentials, right? That's super simple.
[00:01:09] T: Actually, I think the best practice approach in 2021 is send the last four of your social and your mother's maiden name to @gloomylumi.
[00:01:23] AR: No. I don't think that you should paste your credentials in plain text. Don't anybody do that.
[00:01:28] T: Write them down in a notebook, obviously.
[00:01:31] AR: Yeah, there you go. I know in the past, I have done different strategies of it. Typically, what I will do a lot of the time is that I will go and I will get the API and actually capture some JSON from it, just like a standard response thing that I need.
[00:01:50] AC: Okay, but what if the API doesn't exist yet?
[00:01:53] T: Yeah. I was like, “Did I misunderstand the question?” I think, he said there was nothing there.
[00:01:59] AR: Oh, then I will cry and wait for the devs to finish making the endpoint that I need. Clearly, that's the best option right there. No, I would make a file. I'd make definitely make a separate JSON file. I would have some form of JSON blob somewhere that I either handwrite, or if the API exists, and I just want to not have to hit the API, be able to consistently make that thing I would have it stored. Also, depending on how much time and energy you have, you may be able to magically generate some of that information.
[00:02:41] T: Well, not all of us are unicorns, Alex. Do you want to expand on that for the class?
[00:02:46] AR: I'm looking at the Python package. Hold on.
[00:02:50] AC: A thing I will sometimes do is – occasionally, I have to work with data that well, API currently exists, new fields are going to be added to it that aren't available yet. What I like to do is yeah, grab an output and then use a map function to add in the new fields. A lot of times, it'll be a date field or something, so I'll just use a randomized date function and have it write to a new file. Because originally, I was just adding those dates by hand and oh, my God, that is annoying and tedious. Why not just let node do the work for you?
[00:03:34] T: Yeah. I guess, maybe it also depends on what you need the data for, or you're building for the API, because usually, I was mostly just building reusable components. The back-end developer would be like, here's the shape of the API data. That is definitely not going to change 30 times in the next two days. I paste that into my new component data, because like, I don't need to do anything fancy and then make the component work with that shape. Then delete it and replace it with the real data when the API is ready.
[00:04:05] AC: You said you had no experience doing this.
[00:04:07] T: Well, I didn't mock the data myself. Somebody else mocked it. Then the process mocked me.
[00:04:13] AC: Oh.
[00:04:17] AR: There are packages out there that you can say, here's what the data structure will look like. It'll give you mock data objects, right? If you could be like, “Here's what my data is going to look like. It's going to have a name and that's a string, and then it's going to have this thing and that's a number, and then it's going to have this thing, that's a date or whatever.” It'll just –
[00:04:42] AC: Nice.
[00:04:43] AR: Make a bunch of stuff and it would be great.
[00:04:44] AC: Does it that make that sound when you use it?
[00:04:46] T: I hope not.
[00:04:46] AR: It does. I don't know why they included that sound effect with it.
[00:04:50] T: Are you sure it's included and not a cat is getting into a box coincidentally, every time you run the package?
[00:04:56] AR: That may be, too. It may be that a cat is just getting into a box.
[00:05:02] T: It sounds like, to run this package, you'd need Python, which I don't know if things have changed with the newest Mac OS’s. I always felt like, running Python was a headache, because, is it Python 2? Is it Python 3? Okay, I don't have Python 3. Okay, I’ll install Python 3 the alias is not right. It's not running.
[00:05:17] AR: The specific package that I was thinking of off the top of my head is called Hypothesis, which is a Python package.
[00:05:23] T: Hypythesis was right there, or Pytho – That would be too hard to say. Pythothesis.
[00:05:29] AC: Nope. I can’t. I tried.
[00:05:33] AR: It's really meant for creating – very quickly creating mock data for you, to be able to run tests. You're not reusing, you're not handwriting the test. You're like, this should take a string and make your stuff. I think, it has some ways that you can – you do some stuff like that. That is where I've experienced it before. However, I know that there are other packages in other languages that do similar things.
[00:05:58] T: I feel like, there must also be a site that does this or something, which personally, I think is ideal, because I don't do everything in my terminal. I don't want to install something just to make fake data, then you use once.
[00:06:09] AC: Even if someone is yes, say, providing you the JSON for the data, I know that sometimes you need to actually be able to figure out the integration part of the API before the API is ready. Because a lot of times, you're going to need to transform the data somehow, once you get the data. You need to be able to make sure that all of your async functions are worked out properly.
I have seen a few different options for doing things like that. Specifically, someone suggested a – I wish I could remember the name of this website. For an interview, I had to load fake data into a website, and then hit that as an API. I wasn't a huge fan of that. It felt very clunky. One thing I have found that I really like is Macoun. It essentially just lets you create the API, you specify the endpoint, and then you just paste in the data you want it to return. You can specify various headers and things like that. It's a pretty robust way of mocking an API endpoint.
[00:07:13] AR: That's really nice. Yeah, I'm looking at this. This is very nice-looking. Yeah, another one that I've used sometimes, especially if I'm just troubleshooting something, and I don't necessarily need a specific data structure or anything like that, but I need to be able to test responses, like error responses, or something like that. Httpbin.org is a great free resource that basically echoes what you send to it sometimes. You have lots of different options. You do get, post, put, patch, delete, whatever. You can get all the various error numbers that you want, and all of that stuff.
It's a good resource for if you're doing a thing, and you're like, “What am I sending? Why can't I see what I'm sending? What am I sending?” That's a really good way to get the response that you're looking for, and do a bunch of things like that.
Another one that I've heard about that I haven't had the opportunity to use, but I think is fantastically exciting, because you could – It's a combination of some of these. It also would be a very good way to run a testing suite, is if you're wanting to test an integration test of make sure the whole application works, but you don't want to be hitting the real API, the thing that I've seen that I need to find a good project to use this on is called Mock Service Worker, where it will install a Service Worker for your project.
When you spin it up, the ServiceWorker will run and will intercept API calls. You never actually hit the API, but you can respond with the response that you want. You could have pre-defined endpoints and be like, “If I try to do this thing, it's going to give me this type of error. If I’m trying to do this thing, it's going to do this.” It's a Service Worker, so it's all in the browser. It just does its stuff. Then you can keep that locally within your test. I had heard about this approach before. I think, it's really smart, because it allows your application to function the way that it's supposed to, and it doesn't know any better. The Service Worker part becomes whatever you want it to be. It can proxy through, or you can have it actually catch responses and do something with it. That's always good.
[00:09:32] T: If you already have a working API, why would you want to go through the trouble of making all these fake responses, instead of actually hitting the endpoint?
[00:09:40] AC: Say, you're on AWS, and it costs money every time you hit that API, or there's a lot – I work for a health care company, and so we have to be HIPAA compliant, so we're a SOC2 compliant, so we have all the security stuff in place and it can get really annoying to run integration tests on to that. Trust me, I know. No, that sounds awesome. I looking forward to look into that.
[00:10:05] AR: Another thing that it's good for too is just local testing in general. If you're wanting to be able to run tests quickly, having to run your tests against an actual API, that can take a while, because you're having to do a full-on HTTP requests, they're having to go all the way up to the database, get all the things and come back. Each request could take –
[00:10:26] AC: 300 milliseconds.
[00:10:28] AR: Yeah, 300 milliseconds. That stacks up. That means that if each test is one API request, then you can do three tests a second, basically. Yeah, that doesn't seem much if you have five tests. It will open in a couple of seconds. If you have a 1,000 tests, suddenly, that's going to take a little bit. Being able to do something where rather than having that delay, that 300-millisecond delay, it's instantaneous. You can bypass a lot of the slowness of these tests, especially if you're not wanting to have to actually test the API itself. If you're wanting to test the functionality of the front-end, then that could be a thing that would help move things along a little bit.
[00:11:17] AC: Fun fact about the product I currently work on. We technically maintain two completely different versions of our API; one that runs on express, purely for local development. Then one that's actually deployed to our AWS CloudFormation, whatever, whatever. I don't fully understand our infrastructure. I mean, fortunately, we have separated out the logic in a way that the controller is utilized by both APIs. I have to maintain a completely separate API in express, just so I can develop locally.
[00:11:59] AR: Wow. Wow.
[00:12:03] T: You might say that SOCs.
[00:12:07] AC: Wow.
[00:12:08] T: Wow.
[00:12:09] AR: Wow.
[00:12:11] AC: Yeah. It allows me to develop locally without having to use a database, which it does mean that for certain things, it's not great. Obviously, I'm not going to have any persistent data. If I'm trying to work on changing the state of things, it can get a little tricky. There are certain things I just never implemented, so we'll always air out locally. At least, I know that our error handling works on those.
[00:12:42] T: I do you feel like data transformation is one of the most painful parts of dealing with APIs, especially when the API is not in place. Because ideally, if you're in that sweet spot of you need to be doing something with an API, but the API hasn't been built yet, then you would think that the front-end usage of the API would dictate the shape of the data. In reality, you often have no say in what the shape of the data is, so you do all these transformations. Then the API changes again to be better shape. Nobody asked you about the better shape, but now there's a better shape, and so you have to redo all your API transformation logic. I think that process can be pretty painful.
[00:13:20] AC: Yeah. We do analytics. The way that data is for data people is very different than say, how I want to consume it. We literally have an entire layer on the backend that is just designed to transform the data into the structure that will be sent to the front end. Because yeah, data itself is often not that useful, if it's how you then make it into something readable by – Honestly, and it's best if it's readable by both humans and machines, because yeah. No, we would intentionally made it, so that the way that the data is stored is completely separate from the needs of the API.
[00:14:05] T: Thank goodness. Yeah, because I think sometimes there is at least a couple different paradigms. Some people would between the two prefer making it human readable, where others would prefer keeping it the shape of the data for the database. That really only serves that one juncture, where you have to send data to the database, and is otherwise, often, mostly unhelpful.
[00:14:27] AC: Yeah. The other thing is it allows us to use the same shape of data for let's say, different healthcare organizations, while keeping their data completely isolated from each other. The old plug and chug.
[00:14:45] AR: This also ties into data structures, and where is your source of truth of what the data structure is. If the only source of truth is just call the API to get some data, or something like that, then If you're going to have problems. I don't care. Having some definition of what that data structure is somewhere of like, when we get a data object back, it's going to look like this. It makes it a lot easier to also do things with it programmatically, too.
[00:15:21] T: Okay, but what do you mean somewhere? Because technically, if I can get it by hitting the API, then it's somewhere, right?
[00:15:28] AR: Right. I'm saying, my experience with this will go down this route. My experience with this is in Python.
[00:15:36] T: Every time you say this route, I always wonder what all of the other potential routes are, and if one – Anyway, keep going.
[00:15:43] AR: I mean, we can talk about Ruby on Rails that I've not used since version 0.83. In Python, there is a web framework called Django. With Django, a big part of it is that you define your data model. You say, here is what this piece of data is. I'm going to have a book and my book has a title, and that is a string. Then I have a author, and that is of type author. Then you can make an author type. Then they're linked to each other. You define your data structure. You're like, how your data connects to each other, and relates to each other and all this stuff. Then it has tools where you can just be like, migrate this, and it automatically populates your database with all the correct tables and columns and whatnot.
I think, I was talking to someone about this just the other day, I think Redwood JS does something similar like this, where you can define your data model. That's what I mean. It's like, having somewhere where you define that data model. We can always say like, you could define it as a TypeScript type. Yeah. I said the T word.
[00:16:57] AC: I’m not going to lie, I do like interfaces, for that reason.
[00:16:59] AR: Yeah. They’re pretty great. But that's having actually defined some somewhere is helpful. Another option that you can do that is more helpful than you realized, is something like an open API spec file, where there is a consistent way of defining what data is and how you can consume it and all sorts of fun things like that.
[00:17:31] T: What is that?
[00:17:34] AR: Back in the day, there was a thing called Swagger.
[00:17:39] T: People still use it now. Why are you making it sound a million years old?
[00:17:41] AC: Yeah. It’s still a thing.
[00:17:43] AR: Well, no, no, no. Swagger was the original implementation, where it was a way to define API files, like an API, what it does, and all that stuff. There's swagger version one and Swagger version two. At that point, it became prevalent enough. Swagger is actually a company. The format became prevalent enough. People were like, “We don't like that a single company is controlling this format.” The company was like “We hear you.” They made the open API spec, which is basically, Swagger 3.0. With open API, spec three is the new version of Swagger, but it's actually controlled by not the company.
[00:18:27] AC: You can utilize it and things other than just Swagger.
[00:18:30] AR: Yes, and you can utilize it and things other than just Swagger. It's a way to define APIs. You get to say, here are my routes. Here are the parameters that I'm expecting. Here are the methods you can use. Here's the type of data structure that it will return. Here are the different response types it could possibly return. It might return JSON. It might return HTML. It might return XML.
[00:18:56] T: Is that its own separate thing, like how, for example, the docs for my app might live on their own separate site in their own separate repo, or whatever? Or is it somehow integrated into the flow of that?
[00:19:07] AR: Yes.
[00:19:07] AC: It can be both.
[00:19:08] AR: It can be both. There are plugins, going back to my bad example, but we're on a Vue podcast, but I'm going to talk about anyway, Python. With Django, there are plugins, where –
[00:19:17] T: You wouldn’t talk about it on a React podcast.
[00:19:20] AR: No, I wouldn't. They really don't like whitespace. With Django, you have your data models that you can define. There are plugins where you can say, “Hey, generate an open API spec for me, based on what my data structure is how my application is laid out.” There are ways where it can go both ways of rather than the application defining the open API spec, the application – or, rather than the open API spec defining the application, the application can define the open API spec.
I've also seen it where you can use an open API spec file, and that is where your error messages go. That is where all of these other things go. Then, you have your application, use that information. You can have technical writers updating information in an open API spec file, and then the application itself is using it. Yeah, there are options. You can go both ways. You can have them two completely independent things that just function independently of each other completely. That's a thing that happens. Yeah. All of that is to say, there are lots and lots and lots of different ways of defining data and data structures.
[00:20:32] AC: There are libraries that will use JS doc annotations to generate your open API spec.
[00:20:40] AR: Nice.
[00:20:41] AC: Not just Python.
[00:20:42] AR: Yeah. Yeah, yeah, yeah. Python was the only example I had off the top of my head. I have not attempted to do that in JavaScript.
[00:20:50] T: I liked how you were like, “This is a Vue podcast, so I'm going to go ahead and use the Python example.” I’m still trying to –
[00:20:56] AR: Trying to talk out my ad that I don't know.
[00:20:59] AC: I thought that's what you as a white man were supposed to do?
[00:21:02] AR: Yeah. Yeah. Well, some days, I’m not going to try as hard to be.
[00:21:09] T: How much of this Swagger maintenance stuff, or API definition maintenance stuff in general, fall on the person consuming the API, versus the person creating the API? How often do we think this is within the realm of front-end, versus some other subset of web development?
[00:21:31] AC: It really should be on the backend. Because like I said, one of the easiest ways to do it is to use annotations within your backend files. Really, yeah, the backend developer, as they're building the API should just be adding those annotations to generate the spec. If they're not, it's certainly not the responsibility of the front-end developer to go back in there and go into their files and add the annotations that they failed to add.
[00:21:58] T: I was going to say, I don't know if I'm reading too much into this. I felt like, should was doing a lot of heavy lifting there.
[00:22:04] AC: I mean, yes. I would say that if you're in a situation where you're the front-end dev having to go into backend files to add annotations, you should probably try to find a different place to work.
[00:22:20] T: Let's say that you don't know anything about mocking data, or playing with APIs, where would be a good place for someone to learn more about that, maybe in general, but also within the Vue context specifically? Because I do feel like that that's something that's not really covered by the docs, the last time I checked. When you all are make an API call, do you generally make it just right in the component that needs it? Or do you do it in some special other file?
[00:22:46] AC: Oh, man. We could literally do an entire episode on that.
[00:22:49] AR: Was this now, where to put your API calls, as the episode. For me, I always create a data abstraction layer of sorts, where I say, when you want data, use this function, and it will give you data. Then I don't care where that data comes from, I just need data to come out of it eventually. If you can split out all of the data stuff into its own thing, then one option is you can just mock your data function call, and just return some data that way.
[00:23:40] AC: Which yeah, I've done that. I do think it's important to have an API abstraction within your Vue app and not just be directly calling Axios, or whatever you're using in a component. You should have a function in between that's calling Axios, so that yes, so that makes it very easy to mock that when running tests.
[00:24:02] T: I mean, it also sounds like another potential advantage there is adding this cushion in between, even though it's extra work sometimes, because, for example, that pattern that Chris talked about a while ago when you're developing a component library, but you also want to use an external component library, and you want to have a wrapper around it, so that if you change your outside component library, then at least the APIs for the components that you're using doesn't have to change across your app.
[00:24:31] AC: Exactly. One thing that I actually found was pretty useful is at one job I had, we did factory functions for our API. Literally, you would hand it your success and failure callbacks, and then it would just plug those in as needed within the function. Yeah. That way, it allowed us to always be utilizing the same function for any given endpoint, but it also allowed us to handle it differently depending on where were using it.
[00:25:01] AR: Another place to look and get more information about this type of stuff, too, is Cypress actually has a network intercept command where you can say, “Hey, look for any outgoing stuff to these addresses.” You can do it on a per test basis. Then that way, you can write their mock the data if you need to, or intercept the data and change it, add fields, whatnot, remove fields. Be like, “It should blow up if this thing is not available, or something.” Then that way, you can just do it right there in your tests in the browser. Shout out to Cypress, because they're cool.
[00:25:51] T: Also, just Googling, it looks like a few of these apps that let you test your endpoints and stuff have a few guides on API mocking. That might be another resource. I'll add them in the show notes, but I haven't used any of them, so I can't speak to them. If anybody knows, or has a favorite resource for that, you know who to at to give us that info.
I think it's tough, because a lot of times, this stuff, it's not really stuff that you can learn yourself, or is covered by classes, or blog posts, or whatever. It's something you learn on the job, either by reading the existing code, or somebody tells you how to do it. Which means that if you're in a situation, like we talked about one of our earlier episodes, like you're the only dev or something, or you're new to the role and nobody is there to show you how to do things, you're in trouble.
[00:26:43] AC: That's why you just listen to podcasts like this.
[00:26:46] T: We gave them no reasons?
[00:26:50] AR: Yeah. If you really want to learn how to mock things really well, just listen to Ari and Tessa talk to me a lot, then there we go. You will learn how to mock things.
[00:27:02] T: Don’t you mean the other way around, Mr. Actually?
[00:27:05] AR: Well, actually.
[00:27:07] AC: Well, actually. If you really just want to get practice doing it, build a side project where you don't build the API until the end.
[00:27:19] T: Or apply to a bunch of jobs and they give you a take bone challenge.
[00:27:22] AC: That too. Yes. No, a lot of my worst mocking experiences came from take home challenges.
[00:27:32] T: Are there any really painful, or memorable mistakes or good decisions that y'all have made when it comes to working with APIs and mock data that you wish you had known earlier in your career?
[00:27:47] AR: Don't trust mock implementations of things. Don't. You don't have full tests, if you only test based on a mock. My best example of this is we were using Google Map. There's a mock library for Google Maps, that allows you to run it in and tests. We were using this. The mocks were wrong. They were wrong, and they're made by Google. They are not implemented the same way as the actual Google thing. It screwed me up.
[00:28:31] T: Meaning like, the shape of the data was wrong?
[00:28:33] AR: No. The interface for it was wrong. I think, in the real Google Maps, they define things on the – using dot prototype, like data to objects. In these mocks, they had it as ES6 classes. If you went to inspect the prototype, you couldn't, because none of the things would show up, because that's an ES6 class thing. It was complicated. It was a very weird, complicated, very specific thing. But because there was this slight implementation difference, it completely did not – You couldn't do the thing that we were trying to do.
[00:29:10] T: It sounds like then, that's another reason that auto generating your API docs is really important. I would guess that the auto generation by itself is not enough, depending on how thoroughly, or not thoroughly you've set up the annotations or whatever. Everybody is nodding so vigorously.
[00:29:26] AR: Yeah.
[00:29:27] AC: Yes.
[00:29:28] T: Just like, wait. I don't know if we all remember, but I feel like, everyone here remembers the old days of the Angular JS auto docks that were famously wonderful.
[00:29:38] AC: I don't remember that.
[00:29:39] AR: Any documentation from Google, really, any of the – if you try to go look up any of the Google documentation on a lot of different things, it's very clearly automatically generated from some form of source code, and it is horrific.
[00:29:56] T: I would say, Google Apps Scripts docs are surprisingly okay. The acronym on the other hand, not great.
[00:30:05] AC: Just got that. Nice.
[00:30:12] AR: Don't assume anything. If you're using a mock and something is going wrong, assume it's the mock. That's the only thing to assume is that if you've verified it's not your code, it's probably theirs. It’s probably the mock.
[00:30:27] AC: Yeah, I can't tell you how many times things have worked locally, but once they were deployed, they didn't work, because I failed to make some change in my local mock data that broke everything else. The real thing was trying to interact with it.
[00:30:44] T: Especially when you have a really complicated data shape, or something with a lot of sub-shapes within the larger shape or whatever. It's such a nightmare to update the mock data.
[00:30:54] AC: Yeah, no. One memorable experience with mock data I had was – it was actually when I was interviewing for the current job I have, which I love my job. They gave a very sparse example of some possible mock data you might use. Only, there was a typo in it that broke things. Having to spend part of my precious time, because this was a timed take home, trying to figure out where the typo was, was not super fun. That is why it is usually good to use an editor that's going to give you some guardrails, in terms of missing brackets and whatnot, when you're making fake data. I think, it was a missing bracket that was the problem.
[00:31:48] T: I'm surprised that that wasn't caught and running, testing the app or whatever, linting, anything.
[00:31:55] AC: The data was presented in a markdown file. Obviously, markdown is not going to catch it. Yeah.
[00:32:01] T: For a second, I thought you're going to say a Word doc, or something. I was like, “I guess, it would make sense.”
[00:32:06] AC: No. One step above. All right. Well, with that it is time to move on to picks for this week. Alex, would you like to go first? Actually, you don't have a choice. You're going first. Hah.
[00:32:20] T: It’s more of a comment than a question.
[00:32:22] AR: It's more of a –
[00:32:23] AC: I know.
[00:32:26] AR: My pick this week has actually been picked before, but I don't think it by me.
[00:32:33] T: No, it wasn't.
[00:32:34] AR: It wasn’t.
[00:32:34] T: By you.
[00:32:34] AR: My pick this week is a book. It is called The Gilded Ones by Namina Forna. It was recommended by a previous guest of ours, Amina Foon, and I finally got around to reading it. It was very good. I would like to recommend it, because I thought it was a very good read.
[00:32:56] T: Namina was like Amina’s cousin, right?
[00:32:59] AR: Yes, I believe it’s Amina’s cousin. There is a sequel coming out in March, I think, that I may have already pre-ordered.
[00:33:11] T: Nice.
[00:33:12] AR: Looking forward to that. Expect that in a few months.
[00:33:16] T: This maybe the first time I've seen you pick a book that wasn't linked to watching a show. I hope they make a show, so that I can go watch it.
[00:33:25] AR: It would translate to a show very well, but you would lose a lot of it. You would lose a lot of – there's a lot of the thoughts going on in her head, because you're hearing it. You're seeing everything from her perspective. A lot of the book focuses on working through trauma stuff. It's really interesting. I thought it was really interesting. Yeah, that is my pick.
[00:33:48] AC: Okay. Tessa, do you have any picks this week? I mean, I already know you do, but whatever.
[00:33:53] T: Thus, end the disbelief Ari. You can't break the fourth wall like that.
[00:33:57] AC: Oops.
[00:34:00] T: My first pick is J-crosswords. It is a crossword app, but for Japanese. I don't usually do crosswords. I don't usually play puzzle games in other languages than English. It's fun, because it's just gamified studying. It's just vocab review. I like being like, “Oh, yeah, here's this word and that word,” and I don't have to decipher any obscure clues, which is maybe part of the reason I don't do crosswords. I don't know. I'm just not into them. That's been a fun distraction. It's available on Android and iOS.
My other pick is Trader Joe's chocolate chip cookies. They're the kind that come in a cardboard box with a cellophane window. I like them, because they don't taste like chocolate chip cookies. You can barely even taste the chocolate. They taste like gingersnap cookies, but without a super strong, overwhelming taste and no claying sweet aftertaste. I like them. I couldn't find a link to them on Trader Joe's. Instead, I linked to a blog review where they rated them 2.5 stars. Because again, they don't really taste like chocolate chip cookies, but I enjoy them. Yeah, those are my picks.
[00:35:14] AC: Okay. My pick this week is the show Superstore. I recently re-watched the whole thing. Every time, I'm like, “Wow, this show is great.” I love the banter and the dialogue and it's just very funny. Yeah, you should watch that.
[00:35:30] T: Is this the one with the blue vests and the guy from Mad Men who lost his pinky?
[00:35:34] AC: Yes.
[00:35:35] T: Okay.
[00:35:36] AC: Yes. Yes. If you've watched Mad Men, it's a little hard to watch at first, because you're just like, “That guy lost his mind on a Mad Men. Is he okay? I'm not sure.”
[00:35:47] T: That's not all he lost.
[00:35:50] AC: Yes. No. Yeah, as far as Ben Feldman and America Ferrera. I love her so much. I think, it's available on Hulu and Peacock. You have some options. Anyway, that is all for this week's episode. If you aren't following us on Twitter, you should. You can do that @enjoythevuecast. You can see pictures of our cats @enjoythevuecats. Be sure to subscribe to the show on whatever podcast app you're using. If you love us, please leave a review. It helps other people find us. Remember to tell everyone about how awesome we are, so that they'll listen to it, too. Then it'll just explode into virality. Yeah, no. Anyway, if you like us, tell other people. We like it when people like us. Speaking of liking us.
[00:36:45] T: Which I know is a really rare trait.
[00:36:47] AC: I know, right?
[00:36:49] T: Not like other podcasts.
[00:36:54] AC: If you do like the show, please consider supporting us on, was it Ko-fi?
[00:36:58] T: Ko-fi.
[00:36:59] AC: Ko-fi, which is ko-fi.com/enjoythevue. Just to be very clear, we don't make any money, whatsoever, off of making this podcast. In fact, some people have actually lost money making this podcast. If you would like to help us keep going, that is the best way to do so. It pays for editing costs and all of that stuff. It's to keep the show going, so it would be super helpful. Anyway, thank you for listening, and until next time, enjoy the vue.
[END]