This is an exercise to implement a PHP-based WHOIS query service for .com
domains using the Slim Framework. The service is structured following Domain-Driven Design (DDD) Hexagonal Architecture and includes Docker support for containerization. It also features unit and integration tests to validate functionality.
- RESTful API Endpoint: Accepts HTTP GET requests to perform WHOIS queries on
.com
domains. - Error Handling: Returns appropriate HTTP status codes for invalid domains, non-
.com
domains, or other errors, conforming to REST API standards. - Hexagonal Architecture: Follows DDD principles for clean separation of concerns and maintainability.
- Docker Support: Fully containerized for easy deployment and execution.
- Testing:
- Unit Tests: Validate domain logic and use cases.
- Integration Tests: Ensure proper integration with the WHOIS service.
I've not used php-di for dependency injection, as it's not necessary for this exercise. However, it would be a good addition for a more complex application. Also I've not used any ORM/persistence for the same reason, but it would be a good addition for a more complex application.
This project follows the principles of Hexagonal Architecture and Domain-Driven Design (DDD) to ensure a clean separation of concerns and maintainability. The project is structured into several layers, each with specific responsibilities.
The Domain layer encapsulates the core business logic and rules. It includes entities, value objects, and domain services. For example:
- DomainName (
src/Domain/ValueObject/DomainName.php
): A value object representing a domain name, ensuring it is valid and a.com
domain. - Domain (
src/Domain/Entity/Domain.php
): An entity representing a domain with its associated properties.
The Application layer contains application services and use cases that orchestrate the domain logic. It acts as a mediator between the domain and the outside world. For example:
- WhoisService (
src/Application/Service/WhoisService.php
): A service that handles WHOIS queries by interacting with the domain and infrastructure layers. - WhoisQuery (
src/Application/Query/WhoisQuery.php
): A query object used to encapsulate the parameters for a WHOIS query.
The Infrastructure layer provides implementations for external systems and frameworks, such as HTTP controllers and WHOIS service adapters. For example:
- WhoisController (
src/Infrastructure/Http/Controller/WhoisController.php
): An HTTP controller that handles requests for WHOIS queries. - WhoisAdapter (
src/Infrastructure/Adapter/WhoisAdapter.php
): An adapter that connects to the WHOIS server to perform queries.
The Port layer defines interfaces (ports) that the Domain layer depends on, allowing the Infrastructure layer to provide specific implementations (adapters). For example:
- WhoisServiceInterface (
src/Domain/Port/WhoisServiceInterface.php
): An interface defining the contract for a service that performs WHOIS queries.
- Inbound Ports: These are interfaces that define how external systems (like HTTP requests) can interact with the application. For example, the
WhoisController
acts as an inbound port, accepting HTTP requests and delegating them to the application layer. - Outbound Ports: These are interfaces that define how the application interacts with external systems (like databases or third-party services). For example, the
WhoisServiceInterface
is an outbound port that defines how the application interacts with a WHOIS service.
- Adapters: Adapters are implementations of inbound or outbound ports. They act as a bridge between the application and external systems. For example:
- The
WhoisAdapter
(src/Infrastructure/Adapter/WhoisAdapter.php
) is an outbound adapter that implements theWhoisServiceInterface
and communicates with the WHOIS server. - The
WhoisController
(src/Infrastructure/Http/Controller/WhoisController.php
) is an inbound adapter that handles HTTP requests and translates them into application commands.
- The
-
Domain Layer:
src/Domain/ValueObject/DomainName.php
: Contains theDomainName
value object.src/Domain/Entity/Domain.php
: Contains theDomain
entity.
-
Application Layer:
src/Application/Service/WhoisService.php
: Contains theWhoisService
application service.src/Application/Query/WhoisQuery.php
: Contains theWhoisQuery
query object.
-
Infrastructure Layer:
src/Infrastructure/Http/Controller/WhoisController.php
: Contains theWhoisController
HTTP controller.src/Infrastructure/Adapter/WhoisAdapter.php
: Contains theWhoisAdapter
WHOIS service adapter.
-
Port Layer:
src/Domain/Port/WhoisServiceInterface.php
: Contains theWhoisServiceInterface
port.
- Testability: The core domain logic is decoupled from external dependencies, making it easy to test.
- Flexibility: The use of ports and adapters allows for easy swapping of implementations.
- Maintainability: Each layer has a clear responsibility, making the codebase more maintainable and scalable.
This structure ensures a clean separation of concerns, making the project robust, maintainable, and ready for future extensions.
This project includes an OpenAPI specification (openapi.yaml
) that defines the API endpoints and their expected behavior. The OpenAPI specification provides a standard way to describe the RESTful API, making it easier for developers to understand and interact with the service.
You can view and interact with the OpenAPI documentation using tools like Swagger UI or Redoc. To do this, you can use one the following links:
- https://editor-next.swagger.io/?url=https://raw.githubusercontent.com/KernelFolla/exercise-php-whois-query-service/main/openapi.yaml
- https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/KernelFolla/exercise-php-whois-query-service/main/openapi.yaml
- https://editor.swagger.io/?url=https://raw.githubusercontent.com/KernelFolla/exercise-php-whois-query-service/main/openapi.yaml
- Docker and Docker Compose
- Clone the repository:
git clone https://github.com/KernelFolla/exercise-php-whois-query-service.git cd whois-query-service-exercise
make start
make stop
You can run Composer commands using the make
command. For example, to install dependencies, run:
make composer install
You can also pass additional parameters to Composer commands. For example:
make composer install --no-dev
To run PHPStan for static analysis, use:
make phpstan
To run PHP CodeSniffer for code style checks, use:
make phpcs
to fix the code style issues automatically, use:
make phpcs-fix
This is an exercise, so contributions are not expected. However, feedback and suggestions are welcome!