Full Stack App Backend: Installation and Usage Manual
Turn a Fresh WordPress Installation Into a Headless Application Backend This manual explains how to install and use the Full Stack App WordPress plugin. The plugin is designed to turn a normal WordPress installation into the backend of a headless website or PHP application. The basic idea is: WordPress continues to provide the administration interface, […]
Turn a Fresh WordPress Installation Into a Headless Application Backend
This manual explains how to install and use the Full Stack App WordPress plugin.
The plugin is designed to turn a normal WordPress installation into the backend of a headless website or PHP application.
The basic idea is:
Fresh WordPress
│
▼
Full Stack App Plugin
│
▼
Custom REST API
│
├── Posts
├── Categories
├── Applications
└── Status
│
▼
Headless Frontend
WordPress continues to provide the administration interface, database, media library and content-management facilities.
The Full Stack App plugin adds the application layer and exposes the information through a custom API.
This means that a developer can install WordPress, install this plugin, create content through the WordPress dashboard and then consume that content from a completely separate frontend.
1. What This Package Provides
The Full Stack App backend provides a reusable WordPress-based API layer.
After installation, the plugin creates its own REST API namespace:
/wp-json/fullstack/v1/
The initial API includes endpoints for:
status
posts
categories
apps
Conceptually:
/wp-json/fullstack/v1/status
/wp-json/fullstack/v1/posts
/wp-json/fullstack/v1/posts/{id}
/wp-json/fullstack/v1/categories
/wp-json/fullstack/v1/categories/{id}
/wp-json/fullstack/v1/apps
The exact API can evolve as the project grows, but the important idea is that the frontend communicates with an application-specific API rather than depending directly on WordPress’s default REST representation.
2. What You Need
For local development, we recommend:
Docker
DDEV
Git
A web browser
A terminal
You do not need to install a separate PHP, MySQL or web server stack on the host machine when using DDEV.
DDEV provides a containerized development environment and supports WordPress directly.
For production, the plugin can be installed on a normal WordPress hosting environment. WordPress requires PHP and a MySQL-compatible database, with HTTPS strongly recommended for a public application.
3. Recommended Development Architecture
For development, we will create two conceptual parts:
backend/
WordPress
Full Stack App Plugin
frontend/
PHP application
HTML
CSS
JavaScript
At this stage we are concentrating only on the backend.
So our first project will look like:
my-headless-site/
└── WordPress
├── wp-admin/
├── wp-content/
│ └── plugins/
│ └── fullstack-app/
├── wp-includes/
└── ...
The frontend can be added later.
4. Create a New DDEV WordPress Project
Create a project directory:
mkdir my-headless-site
cd my-headless-site
Initialize DDEV as a WordPress project:
ddev config --project-type=wordpress
Start the environment:
ddev start
DDEV will create a local HTTPS URL based on the project name, normally resembling:
https://my-headless-site.ddev.site
DDEV’s standard WordPress workflow supports creating the project, downloading WordPress with WP-CLI and launching the site.
5. Download WordPress
Now download WordPress:
ddev wp core download
The WordPress files will be placed inside the project.
You can check the installation with:
ddev wp core version
You should see the installed WordPress version.
6. Install WordPress
There are two ways to complete the installation.
You can launch the site:
ddev launch
and complete the WordPress installation through the browser.
Alternatively, WP-CLI can install it directly.
For example:
ddev wp core install \
--url='$DDEV_PRIMARY_URL' \
--title='My Headless Site' \
--admin_user=admin \
--admin_password=admin \
--admin_email=admin@example.com
DDEV documents this WP-CLI installation workflow for WordPress projects.
For a real project, use a strong administrator password rather than the example password shown above.
After installation, open:
https://my-headless-site.ddev.site/wp-admin/
and log into WordPress.
7. Verify the Fresh WordPress Installation
Before installing our plugin, make sure the basic WordPress installation works.
Check:
Frontend
https://my-headless-site.ddev.site/
Administration
https://my-headless-site.ddev.site/wp-admin/
REST API
https://my-headless-site.ddev.site/wp-json/
The REST API should return a JSON response.
At this point, we have an ordinary WordPress installation.
Nothing special has happened yet.
That is important.
We want the manual to demonstrate exactly what our plugin changes.
8. Install the Full Stack App Plugin
Download the fullstack-app.zip package.
Extract it.
Inside the archive you will find the plugin directory:
fullstack-app/
Copy that directory into:
wp-content/plugins/
The resulting structure should look like:
wp-content/
└── plugins/
└── fullstack-app/
├── fullstack-app.php
├── composer.json
├── app/
├── tests/
├── bin/
└── vendor/
The included vendor/ directory means the packaged version already contains its Composer dependencies.
For the normal installation described in this manual, you therefore do not need to run Composer inside the WordPress installation merely to activate the plugin.
9. Install the Plugin With DDEV
If the ZIP file is downloaded outside the project directory, extract it first.
For example:
unzip fullstack-app.zip
Then copy the plugin:
cp -r fullstack-app my-headless-site/wp-content/plugins/
Or, if you are already inside the WordPress project:
cp -r /path/to/fullstack-app wp-content/plugins/
The important result is:
wp-content/plugins/fullstack-app/fullstack-app.php
That file is the plugin entry point.
10. Activate the Plugin
You can activate the plugin through the WordPress dashboard:
Plugins
↓
Installed Plugins
↓
Full Stack App
↓
Activate
Or use WP-CLI:
ddev wp plugin activate fullstack-app
Check the status:
ddev wp plugin status fullstack-app
You should see that the plugin is active.
11. What Happens During Activation?
The plugin does not create a completely separate application server.
Instead, it hooks into WordPress.
The simplified boot process is:
WordPress
│
▼
Plugin loaded
│
▼
Bootstrap
│
▼
REST API initialization
│
▼
API Registrar
│
▼
Full Stack API routes
The plugin registers its API routes when WordPress initializes the REST API.
This means the API automatically becomes part of the existing WordPress installation.
12. Test the Status Endpoint
This should be our first API test.
Open:
https://my-headless-site.ddev.site/wp-json/fullstack/v1/status
Or use curl:
curl https://my-headless-site.ddev.site/wp-json/fullstack/v1/status
A successful response should look similar to:
{
"status": "ok",
"application": "Full Stack App",
"version": "0.1.0"
}
This tiny endpoint is extremely useful.
If it works, we know that:
WordPress
+
Plugin
+
Composer autoloader
+
Bootstrap
+
REST registration
are all functioning.
13. If the Status Endpoint Returns 404
A 404 response usually means that the custom REST route has not been registered.
Check the following.
Is the plugin active?
ddev wp plugin status fullstack-app
Does the plugin exist in the correct directory?
wp-content/plugins/fullstack-app/fullstack-app.php
Is the REST API working?
Visit:
/wp-json/
Restart DDEV
ddev restart
Check the plugin code
Make sure the plugin bootstrap and API registration files are present.
The custom endpoint should not be tested until the ordinary WordPress REST API is functioning.
14. Create Some WordPress Content
Now the interesting part begins.
The backend needs content to serve.
Create a few normal WordPress posts.
For example:
Post 1
Introduction to Headless WordPress
Post 2
Building PHP Applications With WordPress
Post 3
Why Server-Side Rendering Still Matters
Publish them.
Then open:
/wp-json/fullstack/v1/posts
You should receive a JSON response containing the published posts.
The frontend does not need to access the WordPress database directly.
It can consume this endpoint.
15. The Posts Endpoint
The collection endpoint is:
GET /wp-json/fullstack/v1/posts
For example:
curl https://my-headless-site.ddev.site/wp-json/fullstack/v1/posts
The response contains a data collection and pagination metadata.
Conceptually:
{
"data": [
{
"id": 12,
"title": "Introduction to Headless WordPress",
"slug": "introduction-to-headless-wordpress",
"excerpt": "...",
"content": "...",
"date": "...",
"author": {},
"categories": [],
"featured_image": null,
"link": "..."
}
],
"meta": {
"page": 1,
"per_page": 10,
"total": 3,
"total_pages": 1
}
}
The exact values will depend on the content you created.
16. Pagination
The posts endpoint supports pagination.
For example:
/wp-json/fullstack/v1/posts?page=1&per_page=10
The two important parameters are:
page
per_page
For example:
?page=2&per_page=5
requests the second page with five posts per page.
The API also returns:
total
total_pages
so that a frontend can construct its own pagination interface.
17. Searching Posts
The posts endpoint also supports search.
For example:
/wp-json/fullstack/v1/posts?search=wordpress
The API searches the published posts and returns matching results.
This means the frontend can implement a search interface without knowing anything about WordPress’s internal search implementation.
The frontend only needs to construct the appropriate API request.
18. Sorting Posts
Posts can also be ordered.
For example:
/wp-json/fullstack/v1/posts?orderby=date&order=DESC
or:
/wp-json/fullstack/v1/posts?orderby=title&order=ASC
Supported ordering values are deliberately controlled by the backend.
This is important because API parameters should not be treated as arbitrary instructions to the database.
The plugin validates incoming values before constructing the WordPress query.
19. Categories
The category endpoint is:
GET /wp-json/fullstack/v1/categories
Open:
https://my-headless-site.ddev.site/wp-json/fullstack/v1/categories
You should receive a collection similar to:
{
"data": [
{
"id": 4,
"name": "Technology",
"slug": "technology",
"count": 3
}
]
}
You can also request an individual category:
/wp-json/fullstack/v1/categories/4
where 4 is the category ID.
20. Filtering Posts by Category
Once you know a category ID, you can use it to filter posts.
For example:
/wp-json/fullstack/v1/posts?category=4
This allows the frontend to construct category pages without needing to know how WordPress performs the underlying query.
The flow becomes:
Visitor
↓
Category page
↓
Frontend
↓
API request
↓
/posts?category=4
↓
WordPress
↓
Filtered posts
21. The Application Repository
The most application-specific feature of the plugin is the application repository.
The plugin registers the custom post type:
app_repository
This allows WordPress administrators to manage downloadable applications from the dashboard.
The architecture becomes:
WordPress Dashboard
│
▼
Applications
│
├── Title
├── Description
├── Version
├── Operating System
├── Featured Image
└── Downloadable File
These applications are then exposed through the API.
22. Creating an Application
After activating the plugin, look for the application repository section in the WordPress administration area.
Create a new application.
For example:
Title:
My Linux Application
Version:
1.0.0
Operating System:
Linux / Ubuntu
Add a description.
Add a featured image if required.
Then associate the application’s downloadable ZIP file using the application’s file metadata.
Publish the application.
23. The Application API
The application collection endpoint is:
/wp-json/fullstack/v1/apps
For example:
curl https://my-headless-site.ddev.site/wp-json/fullstack/v1/apps
A response will contain application data similar to:
{
"data": [
{
"id": "my-linux-application",
"title": "My Linux Application",
"version": "1.0.0",
"description": "My application description.",
"os": "Linux / Ubuntu",
"file": "https://example.com/my-application.zip",
"date": "Aug 2026"
}
]
}
The frontend can now build an application repository entirely from this data.
24. Why the Application File Uses WordPress Media
The downloadable ZIP file is associated with the application through WordPress’s media system.
The plugin stores the relevant attachment ID as application metadata:
app_file_id
The API then resolves that attachment into a usable URL.
This is an important design choice.
The frontend does not need to know:
Which attachment ID?
Which WordPress metadata field?
Which media record?
It receives:
file
and can simply use the URL.
25. API Response Design
The plugin uses a consistent response structure.
Successful collection responses generally follow:
{
"data": [],
"meta": {}
}
Successful single-resource responses follow:
{
"data": {}
}
This makes the frontend predictable.
It knows where the useful information lives:
response.data
and, when applicable:
response.meta
26. API Errors
Errors are also normalized.
For example, requesting a resource that does not exist should not result in an ambiguous response.
The API can return:
{
"error": {
"code": "fullstack_post_not_found",
"message": "Post not found.",
"status": 404
}
}
The frontend can therefore handle errors programmatically.
For example:
404
↓
Show "Not Found"
400
↓
Show "Invalid Request"
500
↓
Show "Server Error"
The application does not need to guess what happened.
27. Testing the API With curl
For development, curl is an excellent way to inspect the backend.
Test status:
curl https://my-headless-site.ddev.site/wp-json/fullstack/v1/status
Test posts:
curl https://my-headless-site.ddev.site/wp-json/fullstack/v1/posts
Test categories:
curl https://my-headless-site.ddev.site/wp-json/fullstack/v1/categories
Test applications:
curl https://my-headless-site.ddev.site/wp-json/fullstack/v1/apps
Pretty-print JSON with jq:
curl -s \
https://my-headless-site.ddev.site/wp-json/fullstack/v1/posts \
| jq
This is often much faster than debugging a frontend when we simply want to know whether the backend is returning the expected data.
28. Testing With the Included Scripts
The plugin package also contains API test scripts:
tests/
├── api-posts.sh
└── api-categories.sh
These scripts can be used to test the API from the command line.
Before running them, inspect the configured base URL inside the scripts and make sure it points to your local WordPress installation.
Then make the scripts executable if necessary:
chmod +x tests/api-posts.sh
chmod +x tests/api-categories.sh
Run:
./tests/api-posts.sh
and:
./tests/api-categories.sh
These tests are useful because they verify the actual HTTP interface rather than merely testing individual PHP functions.
29. Understanding the Plugin Internals
Once the backend is working, it is useful to understand how the package is organized.
The important classes are:
app/
├── Bootstrap.php
└── Api/
├── Registrar.php
├── Rest.php
├── Status.php
├── Posts.php
├── Categories.php
├── Apps.php
├── ApiResponse.php
├── ApiError.php
└── ErrorResponse.php
Their responsibilities can be summarized as:
| Class | Responsibility |
|---|---|
Bootstrap | Starts the application |
Registrar | Registers API modules |
Rest | REST-level handling and normalization |
Status | Health/status endpoint |
Posts | Post endpoints |
Categories | Category endpoints |
Apps | Application repository |
ApiResponse | Standard success responses |
ApiError | Standard API errors |
ErrorResponse | Error response handling |
This separation is what allows the plugin to grow without becoming one giant PHP file.
30. Adding the Plugin to an Existing WordPress Site
The plugin can also be installed into an existing WordPress installation.
The process is simpler:
Existing WordPress
│
▼
Copy fullstack-app/
│
▼
wp-content/plugins/
│
▼
Activate Plugin
│
▼
Custom API
There is no requirement to rebuild the WordPress installation simply because you want to add the API layer.
However, before installing it on an existing production site, make a complete backup of:
Database
Uploads
WordPress files
and test the plugin in a staging environment first.
31. The Plugin Does Not Replace WordPress Administration
After installation, WordPress remains the place where administrators manage content.
For example:
Posts
Categories
Media
Pages
Applications
The public-facing frontend does not need to reproduce those administrative interfaces.
This is the central benefit of the architecture.
The backend remains familiar to WordPress users.
The frontend remains free to be completely custom.
32. Using the Backend Without Our Frontend
One of the most important properties of the plugin is that it does not require our PHP frontend.
Once the API is working, another application can consume it.
For example:
WordPress + Full Stack App
│
├── PHP frontend
├── Flutter application
├── React application
├── Vue application
└── Mobile client
Any client capable of making HTTP requests can potentially consume the API.
This is why the API is the real boundary between the backend and the presentation layer.
33. Security Considerations
A headless backend should be treated as an application backend, not simply as a public WordPress installation.
For production deployment:
Use HTTPS
The backend should be served over HTTPS.
Use strong administrator credentials
Never use development credentials such as:
admin / admin
in production.
Keep WordPress updated
The WordPress core, plugins and PHP runtime should be maintained.
Restrict administrative access
The WordPress dashboard is the backend administration interface and should be protected appropriately.
Review CORS
During development, permissive CORS can make local development easier.
In production, configure allowed origins according to the actual frontend domains.
Back up the database
The database contains the content that the API exposes.
A reliable backup strategy is therefore essential.
34. Development vs Production
The development environment might look like:
DDEV
│
├── WordPress
├── MySQL
├── HTTPS
└── WP-CLI
while production might look like:
Internet
│
▼
Web Server
│
▼
PHP
│
▼
WordPress
│
▼
Full Stack App
│
▼
REST API
The plugin itself does not depend on DDEV.
DDEV is simply our recommended development environment because it provides a repeatable local WordPress environment.
DDEV’s project workflow is based around configuring the project, starting the environment and launching the site, while its WordPress integration provides WP-CLI commands inside the project.
35. A Complete Installation Checklist
At this point, a completely fresh backend should have gone through the following process:
- Install Docker
- Install DDEV
- Create a project directory
- Run
ddev config --project-type=wordpress - Run
ddev start - Download WordPress
- Install WordPress
- Log into
/wp-admin/ - Copy
fullstack-appintowp-content/plugins/ - Activate the plugin
- Test
/wp-json/fullstack/v1/status - Create some posts
- Create categories
- Create an application
- Add application metadata
- Add an application ZIP file
- Test
/posts - Test
/categories - Test
/apps - Test pagination and filtering
- Run the included API tests
If all of these steps succeed, the backend is ready to be consumed by a frontend.
36. The Finished Backend
After completing the installation, we have transformed a completely ordinary WordPress installation into:
HEADLESS BACKEND
┌───────────────────┐
│ WordPress │
│ │
│ Posts │
│ Categories │
│ Pages │
│ Applications │
│ Media │
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ Full Stack App │
│ Plugin │
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ REST API │
│ │
│ /status │
│ /posts │
│ /categories │
│ /apps │
└─────────┬─────────┘
│
▼
JSON responses
The WordPress installation is now ready to serve as the backend for a separate application.
37. What Comes Next?
This backend package is only half of the reusable system.
The second package is the frontend.
The frontend package contains:
PHP
HTML
CSS
JavaScript
and provides the public-facing application layer.
The two packages therefore have complementary responsibilities:
FULL STACK APP BACKEND
│
│ API
▼
PHP HEADLESS FRONTEND
│
▼
Browser
The backend manages the information.
The frontend turns that information into an experience.
In the next manual, we will take the second package, configure it against a WordPress backend, and show how to use it as the foundation for a fast, lightweight headless website.
That is where the two halves of the project finally meet.