{"id":20765379,"url":"https://github.com/jklzz02/Cities-Rest-API","last_synced_at":"2025-05-11T08:34:01.217Z","repository":{"id":263117305,"uuid":"889388651","full_name":"jklzz02/PHP-Rest-API","owner":"jklzz02","description":"Simple PHP rest API example to retrieve cities information","archived":false,"fork":false,"pushed_at":"2024-11-16T09:44:23.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-16T10:23:23.428Z","etag":null,"topics":["api-controller","api-gateway","api-rest","php-oop","php-oop-pdo","php8"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jklzz02.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-16T08:46:54.000Z","updated_at":"2024-11-16T09:44:26.000Z","dependencies_parsed_at":"2024-11-16T10:23:26.353Z","dependency_job_id":"7a91ad16-9d4f-4ee0-bf4a-562cbfb98cf5","html_url":"https://github.com/jklzz02/PHP-Rest-API","commit_stats":null,"previous_names":["jklzz02/php-rest-api"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jklzz02%2FPHP-Rest-API","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jklzz02%2FPHP-Rest-API/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jklzz02%2FPHP-Rest-API/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jklzz02%2FPHP-Rest-API/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jklzz02","download_url":"https://codeload.github.com/jklzz02/PHP-Rest-API/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225028974,"owners_count":17409616,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-controller","api-gateway","api-rest","php-oop","php-oop-pdo","php8"],"created_at":"2024-11-17T11:16:35.584Z","updated_at":"2025-05-11T08:34:01.209Z","avatar_url":"https://github.com/jklzz02.png","language":"PHP","readme":"# Cities Rest API\n\nThis is a learning project to explore REST APIs by creating one from scratch, supporting CRUD operations and authentication via tokens. The database used in the project contains information on over 140,000 cities around the world.\n\n## Base Endpoint\n\n```url\nhttp://domain/v1/cities\n```\n\nThis is the endpoint to make the requests, retrieve cities information, update or delete data. The response will be in `JSON` format.\n\n## GET request\n\n### City by ID\n\n```http\nGET http://domain/v1/cities?id={city_id}\n```\n\nInserting the id as a `query parameter` allows to retrieve the information of the city with that specific id.\n\n#### Example request with ID\n\n```http\nGET http://domain/v1/cities?id=1\n```\n\n#### Example response with ID\n\n\u003cdetails\u003e\n\u003csummary\u003eView JSON Data\u003c/summary\u003e\n\n```json\n{\n    \"data\": {\n        \"id\": 1,\n        \"name\": \"Beijing\",\n        \"country\": \"CN\",\n        \"population\": 18960744,\n        \"lat\": 39.9075,\n        \"lon\": 116.39723\n    }\n}\n```\n\n\u003c/details\u003e\n\n### Cities by name\n\n```http\nGET http://domain/v1/cities?city={your_city_name}\n\n```\n\nUse this `URL` to retrieve the information of all the cities that share the requested name.\nThe search is case-insensitive.\n\n#### Example request with name\n\n```http\nGET http://domain/v1/cities?city=rome\n```\n\n#### Example response with name\n\n\u003cdetails\u003e\n\u003csummary\u003eView JSON Data\u003c/summary\u003e\n\n```json\n{\n    \"data\": [\n        {\n            \"id\": 150,\n            \"name\": \"Rome\",\n            \"country\": \"IT\",\n            \"population\": 2318895,\n            \"lat\": 41.89193,\n            \"lon\": 12.51133\n        },\n        {\n            \"id\": 13582,\n            \"name\": \"Rome\",\n            \"country\": \"US\",\n            \"population\": 36323,\n            \"lat\": 34.25704,\n            \"lon\": -85.16467\n        },\n        {\n            \"id\": 14954,\n            \"name\": \"Rome\",\n            \"country\": \"US\",\n            \"population\": 32573,\n            \"lat\": 43.21285,\n            \"lon\": -75.45573\n        },\n        {\n            \"id\": 77931,\n            \"name\": \"Rome\",\n            \"country\": \"US\",\n            \"population\": 2697,\n            \"lat\": 44.2206,\n            \"lon\": -89.80843\n        },\n        {\n            \"id\": 97045,\n            \"name\": \"Rome\",\n            \"country\": \"US\",\n            \"population\": 1738,\n            \"lat\": 40.88309,\n            \"lon\": -89.50259\n        },\n        {\n            \"id\": 123454,\n            \"name\": \"Rome\",\n            \"country\": \"US\",\n            \"population\": 1019,\n            \"lat\": 44.58506,\n            \"lon\": -69.86922\n        }\n    ]\n}\n```\n\n\u003e**NOTE** cities are ordered by population in a decreasing order.\n\u003c/details\u003e\n\n\n### City by latitude and longitude\n\nTo retrieve a specific city through its latitude and longitude.\n\n```http\nGET http://domain/v1/cities?lat={city_latitude}\u0026lon={city_longitude}\n```\n\nIt suffice to pass `lat` and `lon` as `query parameters`.\n\n#### Example request with latitude and longitude\n\n```http\nGET http://domain/v1/cities?lat=41.89193\u0026lon=12.51133\n```\n\n#### Example response with latitude and longitude\n\u003cdetails\u003e\n\u003csummary\u003eView JSON Data\u003c/summary\u003e\n\n```json\n{\n    \"data\":\n        {\n            \"id\": 150,\n            \"name\": \"Rome\",\n            \"country\": \"IT\",\n            \"population\": 2318895,\n            \"lat\": 41.89193,\n            \"lon\": 12.51133\n        }\n}\n```\n\n\u003e**NOTE** there can't be two cities with the same latitude or longitude.\n\u003c/details\u003e\n\n### City by multiple parameters\n\nTo narrow the results, use multiple parameters.\n\n#### Example request with multiple parameters\n\n```HTTP\nGET http://domain/v1/cities?name=rome\u0026country=it\n```\n\n#### Example response with multiple parameters\n\n\u003cdetails\u003e\n\u003csummary\u003eView JSON Data\u003c/summary\u003e\n\n```json\n{\n    \"data\":\n        {\n            \"id\": 150,\n            \"name\": \"Rome\",\n            \"country\": \"IT\",\n            \"population\": 2318895,\n            \"lat\": 41.89193,\n            \"lon\": 12.51133\n        }\n}\n\n```\n\n\u003e**NOTE** the search is case-insensitive and the results have been narrowed to one.\n\u003c/details\u003e\n\n\n## Setup the Dev Environment\n\n### Language Level and Dependencies\n\nTo run the project is required **PHP 8.3** or higher and [composer](https://getcomposer.org/) in order to use its autoloader and install libraries, alongside the [needed extensions](https://www.php.net/manual/en/pdo.installation.php) for `PDO`, usually enabled by default.\n\n#### Libraries\n\nThe only used library is [vlucas/dotenv](https://github.com/vlucas/phpdotenv) a .env loader.\nIt is used in the [config](/src/config.php) to populate `$_ENV` super global with environment variables.\n\n```PHP\nif (file_exists(BASE_PATH . '.env')) {\n    $dotenv = Dotenv\\Dotenv::createImmutable(BASE_PATH);\n    $dotenv-\u003eload();\n}\n```\n\nNeeded libraries and their versions can be consulted in [composer.json](/composer.json)\nto install needed libraries run in the root directory of the project:\n\n```BASH\ncomposer install\n```\n\n### Create Database and tables\n\nCreate a database of the supported type (Mysql, PostgreSQL, SQLite). In the [sql](/sql) directory, there are schemas for different type of `SQL` supported databases. It will suffice to run the chosen schema.sql script to initialize the empty tables in the database.\n\n### Populate Database\n\n#### Token Table\n\nThe token table is meant for testing authentication for CRUD operation. Sample tokens can be generated using the [token generator](/bin/tokenGenerator) script.\nMake sure to give execute permission to the script before trying to run it.\n\n**Linux/MacOS**\n\n```bash\nchmod +x bin/tokengenerator \n```\n\nNow simply run the script with this command  to generate a sample Token.\n\n```bash\n./bin/tokenGenerator\n```\n\n**Windows**\n\nAssuming that **PHP 8.2** or higher is installed in the system.\n\n```cmd\nphp /bin/tokenGenerator\n```\n\n#### Cities Table\n\nIf the database was created successfully it will suffice to run the [seed](/sql/cities_seed.sql) script to populate the database with a sample of 100 cities.\n\n### Config and .env Setup\n\nIn the .env specify the type of database to use, make sure to use `PDO` dsn names for the database type such as: sqlite, mysql, pgsql, sqlsrv.\n\n#### .env example for a SQLite database\n\n```.env\nDB_TYPE=sqlite\nDB_NAME=your_database.sqlite3\nDB_HOST=\nDB_PORT=\nDB_USERNAME=\nDB_PASSWORD=\n```\n\nin the case of a `SQLite` database `DB_NAME` will refer to its path, it will be joined with the root path of the project directory, so it's also possible to indicate a subdirectory.\n\n```.env\nDB_NAME=subdir/your_database.sqlite3\n```\n\nthat's how the [Database](/src/Core/Database.php) class will handle the **DSN**.\n\n```PHP\n$dsn = \"sqlite:\" . BASE_PATH  . $config[\"name\"];\n```\n\n#### .env example for MySQL/PostgreSQL database\n\n```.env\nDB_TYPE=your_database_type # mysql/pgsql\nDB_NAME=your_database_name # name of the created database\nDB_HOST=localhost # or the IP address of the server\nDB_PORT=3306 # or the port that the MySQL/PostgreSQL server uses\nDB_USERNAME=your_username\nDB_PASSWORD=your_password\n```\n\n\u003e**NOTE** username and password are not mandatory\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjklzz02%2FCities-Rest-API","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjklzz02%2FCities-Rest-API","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjklzz02%2FCities-Rest-API/lists"}