CS 478 Homework 1 Reflection

Asiful Islam

1. Coding

How long did you spend on this assignment? If you don’t remember, give a rough estimate. It’s okay if you spent very little/a lot of time on the assignment — answering this question honestly will help us figure out how to balance out this course.

I'd estimate 2-3 hours of total work writing the server code and tests.

Where did you spend the most time? Fixing configuration, figuring out Typescript, designing your API, writing tests, debugging your request handlers, etc.?

I wouldn't have taken as long if I had already been experienced with TypeScript and Vitest, but I had to go through a refresher and learn from scratch since lecture wasn't super helpful. Once I got the hang of writing endpoints and tests from Activity 1a, everything fell into place. I spent more time learning the code than actually writing it and I was able to copy and paste a lot of the code I wrote.

What did you struggle with the most? What would’ve improved your experience on this assignment?

Probably learning Zod schemas and understanding how they work. I was completely new to it, so I had to learn it from scratch and edit the widgets schema to fit books and authors. I did some outside research and it helped a lot with understanding why they're important and how to validate input using them. If I had a page on the course website explaining them in full, that would've helped a lot and improved my experience.

2. TypeScript

Keep track of the bugs Typescript helped you catch and the ones it didn’t catch. What are some of the issues Typescript helped you prevent? What are some of the holes in the type system?

TypeScript doesn't help with string logic or routing errors. For example, I mistyped one of the endpoints as app.get("/books:id") instead of ("/books/:id"), which TypeScript saw as a perfectly valid string. It doesn't help with database schemas or SQL queries either, so when I accidentally tried to filter books by name instead of title, TypeScript didn't help and just viewed the query as text. You can also lie to TypeScript through type casting (such as when you write db.get<BookDB>) to make it think the result is a full BookDB, but it won't be able to tell types are accurate since it can't check the database.

TypeScript does help with variable scope issues. When I tried to write the GET /books, I used name in the parameter array [name], which wasn't defined, which TypeScript immediately flagged in the IDE as I wrote it. It also helps with consistency in response shapes, so when I define Book or Author using z.infer<...>, TypeScript makes sure that it has the exact same properties everywhere (title, author_id, etc.), so it can block you from accessing non-existent properties. Finally, TypeScript works great with Zod, so it can ensure that data from parseResult matches the schema so you don't have to guess anything regarding properties.

What kinds of values did you struggle to type correctly? Are there any Typescript topics that are still confusing you?

I had trouble typing the errors in try/catch blocks, since err is unknown by default. I couldn't access err.message to check for foreign key constraints, so I had to explicitly cast it as error = err as any to read its properties. There's not much I find confusing about TypeScript quite yet just because we're still scratching the surface, but I guess I'd say Generics.

3. Testing

What was your experience writing tests? Was it boring, soothing, rewarding? How did they affect your development process?

Writing tests is kinda boring, but the process of running tests after you're finished and seeing them pass is really satisfying. I'm coming off a term where I took SE 320 (Software Verification and Validation, which involves writing lots of tests), so I'm not super keen on them right now. Tests made the development process a bit drawn out, but they bolstered my confidence a lot and made me understand my code better, so they did help.

Did your tests help you find any bugs? If so, which ones?

Yeah, they definitely helped. My endpoint testing helped me find the routing bug I mentioned earlier where I mistyped "/books/:id" as "/books:id", so I went back and fixed it when I saw my test fail. My tests also verified my error handling, such as throwing a foreign key constraint error when an author who still has books tries to be deleted. It also made sure my status codes were correct.

How would you structure your testing differently in the future? What did you learn while testing?

I wrote the server code first and then the tests after, but since tests help catch bugs, I'd opt for a TDD approach next time where I write tests before endpoints. It would've helped me catch bugs better and earlier to avoid wasting time. I learned that automated tests are the only way to verify database constraints, but they can't check SQL logic. I also realized that test isolation is important, so I didn't make tests dependent on one another and it made writing the test suite way smoother.

4. LLMs

Did you use LLMs to help you write your code? If yes, explain how you used them.

I used Gemini to help teach me Zod schemas and come up with test cases, but that's about it. It's helpful for boilerplate code to save time and reinforce concepts I've learned. Gemini was also able to help me think of more endpoints I needed and ensure my API complies with RESTful principles.

If you used LLMs, reflect on how they changed your experience of coding. Did they make it more or less fun? Did they save you time? How do you think they affected what you learned from this assignment?

LLMs definitely made my coding a lot smoother and more fun. Since it helps clear up confusing topics for me such as type casting and Zod schemas, the assignment went by a lot smoother with less confusion. It saved me a lot of time with writing repetitive boilerplate code like I mentioned earlier and it affected what I learned by helping me understand new concepts and ideas.