Home  >  Article  >  Backend Development  >  How to create API with Pure PHP?

How to create API with Pure PHP?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-04 06:11:01919browse

Como criar API com PHP Puro?

In this project we will create a Simple API using only PHP in any framework. All we will need will be:

  • PHP - Essential
  • Composer - Essential
  • Editor/IDE like VScode or PHPStorm
  • Docker - Preferred but not essential
  • Postman - Preferred, but not essential

Let's start by defining our docker-compose.yml file for our database configuration. If you don't want to use Docker to create a database in containers, a solution is to install the database on your machine. For this tutorial we will use MySQL.

Settings

After creating the folder where our application will be located, we start by configuring docker-compose.yaml:

services:
  mysql:
    image: mysql:9.1.0
    ports:
      - '3306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

Let's break this file into parts for explanation:

services:
  mysql:

In this file we are defining the services that will be used.
I'm naming this service mysql. Attention, the name of this service will be used to connect to the database as host

image: mysql:9.1.0

Next I am defining which image will be used to create our database, for this project I am using version 9.1.0 of mysql.
You can find this and other versions on Docker Hub.

ports:
      - '3306:3306'

The port is being set to 3306. This is the default mysql port!

You can notice that the port is like 3306:3306, this : means that we want to listen to this port on our local machine and not just on the docker container, so we can access it it directly on our machine.

environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

As an environment we must define the credentials for our mysql service.
Therefore, we are defining user, password and database name using environment variables:

MYSQL_USER: api_user // <--- Este é nosso usuário
MYSQL_PASSWORD: api_password // <--- Este é nosso password
MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados
MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root

To start our container, just be inside the folder where the docker-compose.yaml file is located and type the following command in our terminal:

docker compose up -d

This will initialize the mysql service in our container.
If you want to access mysql within the terminal, you can use this command:

docker exec -it <nome do container> bash

After typing this command and pressing enter you will enter the container where the mysql image is running.

The container name is formed by foldername-hostname-number
In this case, the name of our container would be: create-api-php-mysql-1 if our application was created within the "create-api-php" directory.

We will also create a composer.json file, this file will serve as the basis for installing external libraries that will be used in the project. In this project we will only use Dotenv.

services:
  mysql:
    image: mysql:9.1.0
    ports:
      - '3306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

In this line we are adding the most used library for dotenv in php.
You can find the repository for this lib at: Github Vlucas Repository

services:
  mysql:

In the line below we are basically saying that we will use autoload with the default configuration of the PSR-4. The most used PSRs currently are PSR-12 and PSR-4, with 12 being the most used to date. But for now we will continue using the PSR-4.

image: mysql:9.1.0

With these two files created we can give the command

ports:
      - '3306:3306'

It will install the Dotenv library and configure the settings for the desired PSR.
After this command, the composer.lock.

file will be created in our environment

For those coming from the JavaScript world, these files can be compared with package.json and package-lock.json.

You will also see that a folder has been added to your directory with the name vendor. It contains our Dotenv lib and also a very important file: autoload.php.
We do not need to touch or change anything in this file, as it will be responsible for transacting Dotenv information between our other files.

We will also create a file called bootstrap.php, this file is responsible for initializing our application and connecting some important parameters so that everything works as expected:

environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

We can then create the .env file to add the environment variables that will be responsible for connecting to our mysql database.
We then add:

MYSQL_USER: api_user // <--- Este é nosso usuário

We will also create a .env.example file where a copy of this information will be saved in case someone wants to clone our repository or even for us in the future if we want to continue our project, this way we will have the necessary information to know what we need define and what we don't need.

MYSQL_PASSWORD: api_password // <--- Este é nosso password

The reason we will create these two files, one containing all the information and the other containing only part of the information, is because the .env file should not be uploaded to the repository, as it contains confidential information. Let's say that in the future we want to use a third-party API where we need to add a token for access, then we will store this information within the .env file.

To prevent the .env file from being uploaded to our repository we will create a file called .gitignore and add the following information:

MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados

This way we define that the .env file and the entire contents of the vendor folder will not be committed.

With this we have finished configuring our project and are free to continue coding.

Codification

We will create the following directories src/System and within System the file DatabaseConnector.php

services:
  mysql:
    image: mysql:9.1.0
    ports:
      - '3306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

Here we are defining a namespace for this file, so that we can use it in the future within other files.

services:
  mysql:

We will create our class with the same name as the file and create a private variable named $dbConnection passing the value null.
This variable will be responsible for a new instance of this class and connecting us with the database.
We'll see more later when we implement try-catch.

image: mysql:9.1.0

Within the constructor we will create the following variables and check the values ​​captured from the .env file with Dotenv.

ports:
      - '3306:3306'

Still inside the constructor we will do a try-catch to validate the action we want to perform:

environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

Within this try we are trying to create a new instance of our class and passing it into the $dbConnection variable. We are using a PDO module for this where it receives the parameters

  • DSN - Data Source Name or URI
  • - mysql: Being the service/bank we are using.
  • - host=$host; Our Host
  • - port=$port; Our door
  • - charset=utf8mb4; Definition of the utf8 charset for the database
  • - dbname=$db The Name of our database
  • USER - User to login to the database
  • PASS - Password for logging into the database

Error case:

MYSQL_USER: api_user // <--- Este é nosso usuário

We will trigger an exception from PDO and return the error message.
Clearly this is just an example of how we should present errors in a development environment. For production environments, it is good practice to present more concise errors that help us understand the problem more clearly.

Outside the constructor but inside our class, we will create the following function:

MYSQL_PASSWORD: api_password // <--- Este é nosso password

Being responsible for calling our variable containing the instance of our connection.

Remember our bootstrap.php file? Let's add the following lines of code to it:

MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados

Looking like this:

MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root

Inside the folder src we will create another directory with the name Database and inside it the file database_seed.php.
This file will be responsible for populating our database for the first time, so if we want to share this project with someone it will not end up with an empty database.

Inside this file we will add the following codes:

services:
  mysql:
    image: mysql:9.1.0
    ports:
      - '3306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

We import require 'bootstrap.php'; because within our bootstrap file we have already imported the variable that is responsible for instantiating our database.

services:
  mysql:

We create a variable with the name $statement that has a value of Heredoc

image: mysql:9.1.0

Within this Heredoc we will add some querys:

ports:
      - '3306:3306'

Here I am opting for drop table to drop the entire base and then start a new one, however if you want you can remove this line of code.

The following line of code specifies that this table will be used to carry out transactions and will have a connection between the tables. If you want to learn more about this mysql declaration: innoDb documentation

environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

Within the same Heredoc we will add another query:

MYSQL_USER: api_user // <--- Este é nosso usuário

Here we are inserting some data into the person table.

We create a try-catch at the end of the file where we try to initialize the querys and in case of error we return an error message just as we did in the data processing in the codes above.

MYSQL_PASSWORD: api_password // <--- Este é nosso password

Inside src we will create another directory with the name TableGateways and inside it we will create the file: PersonGateway.php.

MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados

The files inside this folder will be responsible for interacting with our database, almost like a Repository.

In our PersonGateway class we will add the following constructor:

MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root

We will add this constructor because our class will be called in other files so that we can trigger some methods of our class.

See the following methods:

Method responsible for listing all users in our table

docker compose up -d

Method responsible for listing a single user from our table

docker exec -it <nome do container> bash

Responsible method to insert a user into our table

{
  "require": {
      "vlucas/phpdotenv": "^2.4"
  },
  "autoload": {
      "psr-4": {
          "Src\": "src/"
      }
  }
}

Method responsible for updating a user's information in our table

"require": {
      "vlucas/phpdotenv": "^2.4"
},

Method responsible for deleting a user from our table

"autoload": {
      "psr-4": {
          "Src\": "src/"
      }
  }

We will create within src a directory with the name Controller and inside it the file: PersonController.php.
The files within this directory are responsible for interacting with our application route. Here we interact directly with the bank, but we could use a services layer and limit all logic and business rules to this layer.
If you want to create the services layer, it would be like this:

services:
  mysql:
    image: mysql:9.1.0
    ports:
      - '3306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

However, our intention is not to delve deeper into this type of architecture, for now we will continue with the controller file:

services:
  mysql:

Inside our PersonController class we will add:

image: mysql:9.1.0

This way we guarantee that we are interacting with a new instance of our database.

We also created a method to process our requests:

ports:
      - '3306:3306'

This header is responsible for transmitting the status code and if a body is created it returns this same body to be viewed.

environment:
      MYSQL_ROOT_PASSWORD: useroot
      MYSQL_USER: api_user
      MYSQL_PASSWORD: api_password
      MYSQL_DATABASE: api_example

We also created the methods that will interact with the routes:

Method responsible for interacting with the user's listing route

MYSQL_USER: api_user // <--- Este é nosso usuário

Method responsible for interacting with the user's creation route

MYSQL_PASSWORD: api_password // <--- Este é nosso password

Method responsible for interacting with the user's update route

MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados

Method responsible for interacting with the user's deletion route

MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root

Methods responsible for validation

docker compose up -d
docker exec -it <nome do container> bash
{
  "require": {
      "vlucas/phpdotenv": "^2.4"
  },
  "autoload": {
      "psr-4": {
          "Src\": "src/"
      }
  }
}

Finally, we will create a directory outside our folder src with the name Public.
This folder is responsible for containing the php display file.
We will create the file inside it: index.php
We will add the following code:

"require": {
      "vlucas/phpdotenv": "^2.4"
},

This file is responsible for setting the headers and checking access to the url. If the access is successful it returns the contents, if not it returns an error.

To access your application, simply upload a server using the internal PHP server:

"autoload": {
      "psr-4": {
          "Src\": "src/"
      }
  }

if you have not initialized the container, type the following command in the terminal:

composer install

Now just use postman or any other application that helps you interact with url.

My social networks:
Github Linkedin

The above is the detailed content of How to create API with Pure PHP?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn