Courses

How to Build Laravel 12 API From Scratch

Create a New Record: POST from HTML Form

Summary of this lesson:
- Implementing POST endpoint for creating categories
- Returning newly created record in API response
- Handling POST requests from Vue.js frontend

Until now, we have been talking about API returning data from the server. Now, it's time to post data. We will create a new category.


For Controller methods, we will use the usual naming.

routes/api.php:

Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
 
Route::get('categories', [\App\Http\Controllers\Api\CategoryController::class, 'index']);
Route::get('categories/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'show']);
Route::post('categories', [\App\Http\Controllers\Api\CategoryController::class, 'store']);
 
Route::get('products', [\App\Http\Controllers\Api\ProductController::class, 'index']);

We will create a new category in the Controller, but what will we return? In a regular form without API, it would usually return a redirect to some page. But in this case, we must return some data in a JSON format. Here, the best practice is to return the created record.

app/Http/Controllers/Api/CategoryController.php:

use Illuminate\Http\Request;
 
class CategoryController extends Controller
{
// ...
 
public function store(Request $request)
{
$category = Category::create($request->all());
 
return new CategoryResource($category);
}
}

Now, let's try to launch this endpoint from the client.

In the client, we set the method to POST and added all the fields with values.

After creating a new category, we see the returned data is the created one. And the status code is 201 Created.

There are more available status codes. You can check them at https://httpstatuses.io.


Let's try to create a category from Vue.js. I made a simple form with the name input, and after submitting it, calls the submit method.

But the main code we need to look at is the JavaScript part.

<template>
// ...
</template>
 
<script setup>
import { ref } from 'vue';
 
const name = ref('')
 
const submit = () => {
axios.post('/api/categories', {
name: name.value
})
.then(response => {
console.log('New Category ID: ' + response.data.data.id)
})
}
</script>

Using Axios, we send the POST request to the earlier added /api/categories POST endpoint with the data, in this case, just the name. After the response is successful, we log the new category ID.

In the network tab, we can see the response.

Previous: Data Pagination via API
avatar

I am learning about Vue and API at the same time and if you are already showing Vue code, it would've been helpful that you also show this part of the code:

I made a simple form with the name input, and after submitting it, calls the submit method.

👍 3
avatar

If you want to learn Vue there are separate courses. This course is only about API.

avatar

I don't expecxt to learn Vue in this course. I am saying that because I don't know Vue yet, I wasted more time trying to figure out how to make this part of the code "simple form with the name input, and after submitting it, calls the submit method."

It would have been easier for me to follow along if the complete code, including the HTML part, was provided from the start, since the JavaScript part was already included. Including the full code would help me and probably others to keep up with the course without getting stuck on technical details.

avatar

You can simply ignore the Vue code and test your API directly with Postman, Httpie or Curl. That will be easy enough to go through it

avatar

Worth keeping in mind that request->all() can be exploited and it is better to do request->only('name'), or whatever fields you expect the client to pass to the API

Obviously this is a simple learning example, but good to teach best practices even still.

avatar

Given that this example doesn't contain any validation - it seems reasonable to have the ->all() in place :)

Now, if we were to have validation rules in place - it's better to use $request->validated() since you will only get fields that were validated and correct

avatar
You can use Markdown
avatar
You can use Markdown