Validating Dice Notation
Introduction
In the previous lessons, you learned how to build a basic Express API for rolling dice and how to create a user-friendly landing page. Now, we will make your Express API more powerful and flexible by supporting dice notation and improving input validation.
Dice notation is a standard way to describe dice rolls — especially in games. By adding support for this notation, you will make your API easier to use and more familiar to many users. We will also ensure that the API handles bad input gracefully by returning clear error messages when something goes wrong.
By the end of this lesson, you'll be able to parse and validate dice notation such as 2d6, d20, or 4d8+2, enforce sensible limits on dice rolls and modifiers, and return clear error messages for invalid input. You'll also learn how to write unit tests to ensure that your code works as expected.
Let's get started!
What Is Dice Notation?
Dice notation is a shorthand way to describe rolling dice, which is often used in tabletop games. The most common format is:
Where:
Nis the number of dice to roll (optional, defaults to1).Mis the number of sides on each die.[+/-K]is an optional modifier to add to or subtract from the total.
Here are some examples:
2d6means roll2six-sided dice and add the results.d20means roll1twenty-sided die.4d8+2means roll4eight-sided dice and add2to the total.3d10-1means roll3ten-sided dice and subtract1from the total.
This notation is popular because it is concise and easy to read. By supporting it in your API, you make the service more convenient for users who are familiar with these conventions.
Why LLMs Excel at Standard Formats
Dice notation is a standard, well-established format used across many games and applications. This is important because Codex and other LLM agents are usually highly proficient at implementing standard formats and patterns. When you ask Codex to implement dice notation, it has likely seen countless examples of this pattern in its training data, so it can generate working code relatively easily.
This principle applies to many other standard formats: regular expressions, date/time formatting (ISO 8601, RFC 3339), JSON schemas, URL patterns, markdown parsing, and CSV formatting. However, LLMs can hallucinate and produce incorrect output. Always review, test, and verify generated code — especially for critical functionality — before deploying it to production.
Parsing and Validating Dice Notation
Let's use Codex to build a parser for dice notation. We'll guide it step by step with clear prompts.
Step 1: Create the Dice Parser
The first thing we need is a function that takes a string like "2d6+3" and extracts the count, sides, and modifier. Ask Codex to create this:
Codex will generate a file with a regular expression like ^\s*(?:(\d*)d(\d+))(?:([+-])(\d+))?\s*$ that matches:
- An optional number (the
countof dice). - The letter
d. - The number of
sides. - An optional
modifier(either+or-followed by a number).
For example, parsing 4d8+2 gives count = 4, sides = 8, modifier = 2. Parsing d20 gives count = 1 (default), sides = 20, modifier = 0 (default).
Step 2: Add Input Validation
Now let's add sensible limits to prevent abuse or errors. Prompt Codex:
These limits ensure that users can't request absurd rolls like 999999d999999, which would waste server resources or cause errors.
Step 3: Review the Generated Code
After Codex generates the parser, review the output carefully. You should verify that:
- The regex correctly handles all valid formats (
2d6,d20,4d8+2,3d10-1). - Missing count defaults to
1. - Missing modifier defaults to
0. - Out-of-range values produce clear error messages.
- The function uses proper TypeScript type annotations for the return value.
This is a good example of where LLMs excel — dice notation is a well-known standard, so Codex is likely to produce a correct implementation. But always review before moving on.
Updating the API Endpoint
Now let's update the /roll/ endpoint to support dice notation alongside the existing count and sides parameters.
Step 1: Add Dice Notation Support to the Route
Prompt Codex to update your existing route:
This way, users can make requests like /roll/?expr=3d10-1 using dice notation, or stick with the older format /roll/?count=2&sides=6.
Step 2: Add Error Handling to the Route
Next, prompt Codex to handle errors gracefully:
Now, a request like /roll/?expr=banana will return:
And a request like /roll/?expr=0d6 will return:
Step 3: Verify the Success Response
For a valid request like /roll/?expr=2d6+3, the response should include the individual rolls, the total (including the modifier), and echo back the parameters:
Test this using the platform's preview feature to confirm everything works.
Testing the Parser and Endpoint
Testing is essential to ensure that your code works and handles errors correctly. Let's use Codex to set up testing and write our test cases.
Step 1: Set Up the Testing Framework
First, ask Codex to configure testing for your project:
Codex will install the dependencies and configure Jest to work with TypeScript. supertest is a library that lets you test Express endpoints without starting the server.
Step 2: Write Tests for the Parser
Now, prompt Codex to write unit tests for the parser:
Codex will generate a test file using Jest's describe, test, expect, and toThrow patterns. Review the output to make sure all cases are covered.
Step 3: Write Tests for the Endpoint
Next, ask Codex to write endpoint tests:
Codex will generate tests using supertest to make HTTP requests against your Express app, and will use jest.spyOn(Math, 'random') to make the random results predictable.
Step 4: Run the Tests
Run the tests with:
Review the results. If any tests fail, you can ask Codex to help fix the issues by describing the failure in your next prompt.
Summary and Practice Preview
In this lesson, you used Codex to enhance your Express API by adding support for standard dice notation, robust input validation, and clear error messages for invalid requests. You guided Codex through creating a parser, updating the API endpoint, and writing comprehensive tests — all through natural language prompts. You also learned that LLMs excel at implementing well-known standard formats like dice notation, while still requiring careful review of the generated output. In the upcoming exercises, you'll put these concepts into practice by guiding Codex to parse dice notation, validate input, and test your API to reinforce what you've learned.
