Feature Implementation Plan: Add Slugs to Entities¶
📋 Todo Checklist¶
- [ ] Create a new database migration to add
slugcolumns. - [ ] Update
CoffeeBeanandRoasterentities with the newslugfield. - [ ] Create a
SlugServiceto generate unique slugs. - [ ] Integrate
SlugServiceinto entities or listeners to generate slugs on create/update. - [ ] Create new API endpoints to fetch entities by slug.
- [ ] Update existing API responses to include the
slug. - [ ] Write tests for the new functionality.
- [ ] Final Review and Testing
🔍 Analysis & Investigation¶
Codebase Structure¶
The project is a Symfony application. Key directories are:
- src/Entity: Contains Doctrine entities (e.g., CoffeeBean.php, Roaster.php).
- src/Repository: Contains Doctrine repositories for data access.
- src/Controller/Api: Contains API controllers.
- migrations: Contains Doctrine database migrations.
Current Architecture¶
The application uses a standard Symfony architecture with Doctrine for the ORM and API Platform (or custom controllers) for the API. Entities are mapped to the database, and repositories are used to query data. Controllers handle HTTP requests and responses. There is no existing slug generation library in composer.json, so a custom solution will be needed.
Dependencies & Integration Points¶
- Doctrine: The
CoffeeBeanandRoasterentities will be modified to include theslugfield. A new migration will be required. - Symfony Serializer: API responses will need to be updated to include the
slug. - Symfony Routing: New routes will be added for the slug-based endpoints.
Considerations & Challenges¶
- Uniqueness: The slug generation logic must handle non-unique slugs by appending a suffix (e.g.,
-2,-3). - Backfilling: Existing entities in the database will need to have slugs generated for them. This can be done in the migration or with a separate command.
- Performance: The
by-slugendpoints should be fast. Adding a unique index to theslugcolumn is crucial.
📝 Implementation Plan¶
Prerequisites¶
- Ensure you have a local development environment set up with a database.
- Make sure you can run Doctrine migrations.
Step-by-Step Implementation¶
- Create a new Doctrine migration:
- Files to modify: a new file in
migrations/ -
Changes needed:
- Run
php bin/console make:migrationto create a new migration file. - In the generated migration file, add SQL to create the
slugcolumn on thecoffee_beansandroasterstables. - The columns should be
VARCHAR(255)and have aUNIQUEindex. - Add a post-migration step to generate slugs for existing records.
- Run
-
Update Entities:
- Files to modify:
src/Entity/CoffeeBean.php,src/Entity/Roaster.php -
Changes needed:
- Add a private
$slugproperty to both entities. - Add
#[ORM\Column(type: 'string', length: 255, unique: true)]attribute to the$slugproperty. - Add getter and setter methods for the
slug.
- Add a private
-
Create a Slug Service:
- Files to modify:
src/Service/SlugService.php(new file) -
Changes needed:
- Create a new service class
SlugService. - Implement a
generatemethod that takes a string and returns a URL-friendly slug. - Implement a
createUniqueSlugmethod that takes an entity and a repository, generates a slug, and checks for uniqueness, appending a suffix if necessary.
- Create a new service class
-
Integrate Slug Generation:
- Files to modify:
src/Entity/CoffeeBean.php,src/Entity/Roaster.php -
Changes needed:
- Add a
#[ORM\PrePersist]and#[ORM\PreUpdate]lifecycle callback method to both entities. - In this method, use the
SlugServiceto generate and set the slug before the entity is saved. - Alternatively, create a Doctrine event listener to handle this logic.
- Add a
-
Create New API Endpoints:
- Files to modify:
src/Controller/Api/CoffeeBeanController.php,src/Controller/Api/RoasterController.php -
Changes needed:
- In
CoffeeBeanController, add a new methodgetBySlug(string $slug)with a routeGET /api/coffee-beans/by-slug/{slug}. - In this method, use the
CoffeeBeanRepositoryto find the entity by slug and return it. - In
RoasterController, add a similargetBySlugmethod.
- In
-
Update Existing API Responses:
- Files to modify:
src/Controller/Api/CoffeeBeanController.php,src/Controller/Api/RoasterController.php - Changes needed:
- Ensure the
slugfield is included in the JSON responses for all existing endpoints that returnCoffeeBeanorRoasterobjects. This might involve updating serialization groups if they are used.
- Ensure the
Testing Strategy¶
- Unit Tests:
- Write unit tests for the
SlugServiceto ensure it generates slugs correctly and handles uniqueness. - Integration Tests:
- Write integration tests for the new API endpoints to ensure they return the correct entities.
- Write tests to verify that slugs are generated and saved correctly when creating and updating entities.
- Test the uniqueness constraint by trying to create entities with the same name.
🎯 Success Criteria¶
- The
slugcolumns are added to thecoffee_beansandroasterstables with unique indexes. - Slugs are automatically generated and saved when a
CoffeeBeanorRoasteris created or updated. - The new
GET /api/coffee-beans/by-slug/{slug}andGET /api/roasters/by-slug/{slug}endpoints work correctly. - The
slugfield is present in all API responses that includeCoffeeBeanorRoasterdata. - All tests pass.