Search code examples
phpapachehttphttpslumen

Testing RESTful API (Lumen) - is the http/https protocol the problem?


I'm following this tutorial https://www.youtube.com/watch?v=6Oxfb_HNY0U to build a small lumen testproject. I'm currently at 27th minute where you are supposed to insert a record through a post request. To do this, I'm using RESTClient http://restclient.net/

So, the last day I already did my best to tackle this problem, and thanks to SO I also could at least in part solve the issue: What does the second paremeter in "json()" do (Lumen/Laravel)?

However, I still get errors instead of new records. When sending a post request to

http://localhost:8080/api/articles

I get this error:

 (1/1) BadMethodCallException

Method Laravel\Lumen\Http\Request::validate does not exist.
in Macroable.php line 103
at Request->__call('validate', array(array('title' => 'required', 'description' => 'required')))in ArticleController.php line 36
at ArticleController->create(object(Request))
at call_user_func_array(array(object(ArticleController), 'create'), array(object(Request)))in BoundMethod.php line 32
at BoundMethod::Illuminate\Container\{closure}()in Util.php line 34
at Util::unwrapIfClosure(object(Closure))in BoundMethod.php line 90
at BoundMethod::callBoundMethod(object(Application), array(object(ArticleController), 'create'), object(Closure))in BoundMethod.php line 34
at BoundMethod::call(object(Application), array(object(ArticleController), 'create'), array(), null)in Container.php line 590
at Container->call(array(object(ArticleController), 'create'), array())in RoutesRequests.php line 376
at Application->callControllerCallable(array(object(ArticleController), 'create'), array())in RoutesRequests.php line 342
at Application->callLumenController(object(ArticleController), 'create', array(true, array('uses' => 'App\\Http\\Controllers\\ArticleController@create'), array()))in RoutesRequests.php line 316
at Application->callControllerAction(array(true, array('uses' => 'App\\Http\\Controllers\\ArticleController@create'), array()))in RoutesRequests.php line 278
at Application->callActionOnArrayBasedRoute(array(true, array('uses' => 'App\\Http\\Controllers\\ArticleController@create'), array()))in RoutesRequests.php line 263
at Application->handleFoundRoute(array(true, array('uses' => 'App\\Http\\Controllers\\ArticleController@create'), array()))in RoutesRequests.php line 165
at Application->Laravel\Lumen\Concerns\{closure}(object(Request))in RoutesRequests.php line 416
at Application->sendThroughPipeline(array(), object(Closure))in RoutesRequests.php line 171
at Application->dispatch(null)in RoutesRequests.php line 108
at Application->run()in index.php line 28

Since I'm new to Lumen/Laravel, I find it hard to guess anything from this error. I don't know if I just mispelled something, didn't pay attention to scope or anything like that.

Now, here is the code which produced this error: web.php (routes), Article.php (the model, residing in app folder) and ArticleController.php (Controller):

web.php:

<?php

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/

$router->get('/', function () use ($router) {
    return $router->app->version();
});
//                was simply 'api' in tutorial
$router->group(['prefix' => '/api'], function($router){
  $router->get('articles', 'ArticleController@showAllArticles');
  $router->get('articles/{id}', 'ArticleController@showOneArticle');
  $router->post('articles', 'ArticleController@create');
});

ArticleController.php

<?php

namespace App\Http\Controllers;

use App\Article;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    //

    public function showAllArticles(){
      return response()->json(Article::get(['title', 'description', 'status'])); // ::get([]) spezifiziert die zu referenzierenden Attribute
                                                                                // ::all() referenziert alle Attribute einer Tabelle/Relation
    }

    public function showOneArticle($id){
      return response()->json(Article::find($id));
    }


    public function create(Request $request){
      //dd($request); //for debugging whether the request is actually being processed

      $validatedData = $request->validate([
        'title' => 'required',
        'description' => 'required',
      ]);


      //dd($request); //for debugging whether the specified fields are required
      //insert record

      $article = Article::create($request->all());
      return response()->json($article, 201);

    }


}

Article.php:

<?php

namespace App;


use Illuminate\Database\Eloquent\Model;

class Article extends Model
{

    protected $fillable = [
        'title', 'description', 'status'
    ];

}

Since the function "create()" in this code is modified compared to the tutorial code (see the answer of ege in the SO question referenced at the top), I tried out the tutorial code as well, where the create() function looks like this:

public function create(Request $request){

  $this->validation($request, [
    'title' => 'required',
    'description' => 'required'
  ]);


  $article = Article::create($request->all());
  return response()->json($article, 201);

}

and I get another error, in this case:

 (1/1) Error

Call to undefined method App\Http\Controllers\ArticleController::validation()
in ArticleController.php line 41
at ArticleController->create(object(Request))
at call_user_func_array(array(object(ArticleController), 'create'), array(object(Request)))in BoundMethod.php line 32
at BoundMethod::Illuminate\Container\{closure}()in Util.php line 34
at Util::unwrapIfClosure(object(Closure))in BoundMethod.php line 90
at BoundMethod::callBoundMethod(object(Application), array(object(ArticleController), 'create'), object(Closure))in BoundMethod.php line 34
at BoundMethod::call(object(Application), array(object(ArticleController), 'create'), array(), null)in Container.php line 590
at Container->call(array(object(ArticleController), 'create'), array())in RoutesRequests.php line 376
at Application->callControllerCallable(array(object(ArticleController), 'create'), array())in RoutesRequests.php line 342
at Application->callLumenController(object(ArticleController), 'create', array(true, array('uses' => 'App\\Http\\Controllers\\ArticleController@create'), array()))in RoutesRequests.php line 316
at Application->callControllerAction(array(true, array('uses' => 'App\\Http\\Controllers\\ArticleController@create'), array()))in RoutesRequests.php line 278
at Application->callActionOnArrayBasedRoute(array(true, array('uses' => 'App\\Http\\Controllers\\ArticleController@create'), array()))in RoutesRequests.php line 263
at Application->handleFoundRoute(array(true, array('uses' => 'App\\Http\\Controllers\\ArticleController@create'), array()))in RoutesRequests.php line 165
at Application->Laravel\Lumen\Concerns\{closure}(object(Request))in RoutesRequests.php line 416
at Application->sendThroughPipeline(array(), object(Closure))in RoutesRequests.php line 171
at Application->dispatch(null)in RoutesRequests.php line 108
at Application->run()in index.php line 28

I'm basically having the same problems with understanding the error as with first error. I've looked up the lumen documentation here: https://lumen.laravel.com/docs/6.x/validation

And again I wonder if I didn't understand the scope correctly (what does "this" refer to here, what object is it, what methods can I actually call from it?).

For the sake of completeness, a screenshot of the table I'm referencing with the eloquent model "Article": https://i.sstatic.net/xJmXQ.jpg

Overall I'm just pretty clueless and I would be really thankful if someone could "give me a lift" ^^


Solution

  • Looking at your modified example (2nd version here of your create() method), The first line of the error shows the problem:

    Call to undefined method App\Http\Controllers\ArticleController::validation()

    So something is wrong with this line in your code:

    $this->validation() ...
    

    Checking the link to the Lumen docs that you include:

    The $this->validate helper which is available in Lumen ...

    So there is a validate() helper - but you're using validation().