skip to Main Content

I am new to Laravel (version 8), and not a big fun of php, but now I need to write a simple API in php, and I have problems.

First, I can login, I got the token. That’s a good part.

My route configuration in api.php looks like this:

use IlluminateHttpRequest;
use IlluminateSupportFacadesRoute;

use AppHttpControllersApiSecurityController;
use AppHttpControllersApiMessageController;

Route::post('/login', [SecurityController::class, 'login']);
Route::get('/messages', [MessageController::class, 'index']);
Route::post('/messages', [MessageController::class, 'store']);


/* Message controller routes */
/* !! if definied like this, not even one /messages endpoint is hited from Postman !!*/
// Route::middleware('auth:sanctum')->group(function ()
// {
//     Route::apiResource('messages', MessageController::class);
// });


/* Security controller routes */
Route::middleware('auth:sanctum')->get('/user', function (Request $request)
{
    return $request->user();
});

My controler for messages:

namespace AppHttpControllersApi;

use AppHttpControllersController;
use IlluminateHttpRequest;
use AppModelsMessage;
use AppHttpResourcesMessage as MessageResource;
use AppHttpResourcesMessageCollection;
use AppHelpersHashGenerator;

class MessageController extends Controller
{
/**
     * Store a newly created resource in storage.
     *
     * @param  IlluminateHttpRequest  $request
     * @return IlluminateHttpResponse
     */
    public function store(Request $request)
    {
        $hash = HashGenerator::generateRandomString($request->text, 10);

        $message = Message::create
        ([
            'uniq' => $hash,
            'text' => $request->text,
            'imageLink' => $request->imageLink,
            'typeID'  => $request->typeID,
            'answerTypeID' => $request->answerTypeID
        ]);

       return new MessageResource($message);
    }
}

Now the problem is that $request are empty, and I got the following message:

Integrity constraint violation: 1048 Column ‘text’ cannot be null (SQL: insert into messages (uniq, text, imageLink, typeID, answerTypeID, updated_at, created_at) values (44f3d0c26f9f8b6338d82cd2ab8ac402, ?, ?, ?, ?, 2021-01-30 16:08:54, 2021-01-30 16:08:54))

The text, imageLink, typeID, answerTypeID fields are empty. If I just tell the function to return the $request it returns [] as an answer.

So what am I doing the wrong way?
What did I miss in the routing?
Why is my $request empty?

I am testing it from Postman. The object that I am sending are:

{
  "text" : "{{$randomLoremParagraphs}}",
  "imageLink" : "{{$randomAbstractImage}}",
  "typeID" : "{{$randomInt}}",
  "answerTypeID" : "{{$randomInt}}"
}

and if I check in console, the request body is there:

text: "Provident libero voluptatem a aut quis occaecati ut nesciunt. Et eius et. Velit blanditiis quo nobis. Odit officiis cupiditate et fuga dolore necessitatibus vero officiis. Eum ut eius sint magnam et ut iure. Non totam deserunt totam veniam.
 
Delectus suscipit est. Ut adipisci asperiores illo. Quas quia consectetur aliquam quidem. Commodi dolores architecto magnam.
 
Necessitatibus voluptatem et quidem ut in reprehenderit alias eaque quia. Velit dolorem facere. Ut itaque vel sunt quod possimus et quo ut voluptatem. Nobis porro veritatis. Ut et modi atque praesentium voluptate voluptate id. Sunt non voluptatibus."
imageLink: "http://placeimg.com/640/480/abstract"
typeID: "397"
answerTypeID: "319"

In header I set the:

Content-Type : application/json
Authorization : Bearer 18|4i3pFHEYcMnG34BTSCKuStDcDPQBot12THXOAu9d

With or without the JWT is is not working.
At the end I need all the MessagesController enpoints to be protected.

My Message class:

namespace AppModels;

use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;

class Message extends Model
{
    use HasFactory;

    protected $fillable =
    [
        'uniq', 'text', 'imageLink', 'typeID','answerTypeID'
    ];

    public function user()
    {
        return $this->belongsTo(AppModelsUser::class);
    }

    public function messageType()
    {
        return $this->hasOne(AppModelsMessageType::class);
    }

    public function messageAnswerType()
    {
        return $this->hasOne(AppModelsMessageAnswerType::class);
    }
}

thnx

4

Answers


  1. Chosen as BEST ANSWER

    After hours of digging, I found a solution, probably not the right one, but it's a solution:

    public function store(Request $request)
        { 
            try
            {
                //this way we can read the json data in the body into an array
                $data = request(['text', 'imageLink', 'typeID', 'answerTypeID']);
    
                $generator = new HashGenerator;
                $hashLength = 13;
                $hash = $generator->generate($hashLength);;
       
                $message = Message::create
                ([
                    'uniq' => $hash,
                    'text' => $data['text'], //access the data in the array using keys
                    'imageLink' => $data['imageLink'],
                    'typeID'  => $data['typeID'],
                    'answerTypeID' => $data['answerTypeID']
                ]);
    
                return $message;
            }
            catch (Exception $error)
            {
                return response()->json([
                  'status_code' => 400,
                  'message' => 'Error',
                  'error' => $error,
                ]);
            }
        }
    

  2. Add uniq, text, imageLink, imageLink, typeID and answerTypeID into $fillable array of the model.

    <?php
    
    namespace AppModels;
    
    use IlluminateDatabaseEloquentModel;
    
    class Message extends Model
    {
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        protected $fillable = ['uniq', 'text', 'imageLink','typeID', 'answerTypeID'];
    }
    

    for more info: https://laravel.com/docs/8.x/eloquent#mass-assignment

    Login or Signup to reply.
  3. At first try to see what’s coming from in the request:

    public function store(Request $request)
    {
       dd($_POST);
    }
    

    Then look for the next step. If it is the problem of mass assignment or guarded ,
    do the following in your model:

    protected $guarded = [];
    

    If it is the problem from frontend , try to solve it there.
    Hope it would help.

    Login or Signup to reply.
  4. Found another way to extract the body data from request, using json_decode() function.

    public function store(Request $request)
        {   
            try
            {
                $body = $request->getContent();
                $data = json_decode($body);
    
                $generator = new HashGenerator;
                $hashLength = 13;
                $hash = $generator->generate($hashLength);
    
                $message = Message::create
                ([
                    'uniq' => $hash,
                    'text' => $data->text,
                    'imageLink' => $data->imageLink,
                    'typeID'  => $data->typeID,
                    'answerTypeID' => $data->answerTypeID
                ]);
    
                return new MessageResource($message);
            }
            catch (Exception $error)
            {
                return response()->json([
                  'status_code' => 400,
                  'message' => 'Error',
                  'error' => $error,
                ]);
            }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search