Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Proposal - Use "array of params" instead $request #15

Closed
robsontenorio opened this issue Dec 29, 2016 · 5 comments
Closed

Proposal - Use "array of params" instead $request #15

robsontenorio opened this issue Dec 29, 2016 · 5 comments

Comments

@robsontenorio
Copy link

robsontenorio commented Dec 29, 2016

Problem

Sometimes i need to call model`s methods, that uses a QueryBuilder instance. So , i "can not trust" on $request object, in this case. Because, not all parameters in current querystring are applied for both QueryBuilder instances.

Proposal

This is my current implementation, for solve my problem, and i would like to share if you. Its a braking change.

Change QUERYBUILDER.PHP

FROM

__construct(Model $model, Request $request)

TO

__construct(Model $model, array $params = [])

QueryBuilder.php

public function __construct(Model $model, array $params = []) {
                 ...

		$this->uriParser = new UriParser($params);

		...
}

UriParser.php

public function __construct(array $params = []) {

		$this->uri = (count($params) > 0) ? '?' . http_build_query($params) : NULL;
                ....
}
               

Example

MODELS/USER


// generic get all items method
public static function listAll(array $params = []) {
		
		$users = (new QueryBuilder(new User, $params))->build()->paginate();
		
		return $users;
	
	}

MODELS/TOURNAMENT

// generic get all items method
public static function listAll(array $params = []) {
		
		$tournaments = (new QueryBuilder(new Tournament, $params))->build()->paginate();
		
		return $tournaments;
	
	}

CONTROLLERS/DASHBOARD

public function recents(Request $request) {


                //now on the same request i can use diferent QueryBuilder instances to filter my collections, based on ARRAY OF PARAMS

		$recentUsers = User::listAll( /*** custom params array here ***/ );
		$recentTournametns = Tournament::listAll( /**** we can even use "$request->all()" to obtain a array of parameters from current request  *** /);
	        
                 return ['users' => $recentUsers, 'tournaments' => $recentTournaments]
	}

@robsontenorio robsontenorio changed the title Proposal - Use $params not $request Proposal - Use $params instead $request Dec 29, 2016
@robsontenorio robsontenorio changed the title Proposal - Use $params instead $request Proposal - Use "array of params" instead $request Dec 29, 2016
@selahattinunlu
Copy link
Owner

Firstly, thanks for proposal @robsontenorio :)
But I did not understand actually why do you need it, sorry. I will be glad if you explain using an example case.

@robsontenorio
Copy link
Author

robsontenorio commented Jan 3, 2017

I have my "list all" methods encapsulated in Models. They are encapsulated, because sometimes i can do some custom queries, like: get relations , order by ... not only LIST ALL.

// Games.php - Chess, Mario , Kings ...

public function listAll($request){
     // return api query builder results
}

Other methods in here: save, delete, update ...

// Platforms.php - PS4, XboxOne

public function listAll($request){
     // return api query builder results
}

Other methods in here: save, delete, update ...

// Player.php - usernames ...

public function listAll($request){
     // return api query builder results
}

Other methods in here: save, delete, update ...

So in my endpoint mysite.com/top i would like to show the top records from some entities.

// RecentController.php - list recent records

public function index(Request $request){
     $player = Player::listAll($request);  // recent players: limit=5&order_by=id,desc
     $games = Game::listAll($request);    // recent games added: limit=20&order_by=id,desc
     $plataforms = Game::listAll($request); //recent plataforms added: limit=10&order_by=id,desc

     // return mounted json 
}

In this scenario above my "list all" method have different behavior depending on parameters. By using current implementation ($request object) i cant use custom filters, because all of them depends on the single $request object.

By, using "array of parameters" in QueryBuilder i can build custom queries. It would be an "untied implementation".

public function index(Request $request){

     // using custom params

     $player = Player::listAll(['limit' => 5, ....]);  // recent players: limit=5&order_by=id,desc
     $games = Game::listAll(['limit' => 20, ....]);    // recent games added: limit=20&order_by=id,desc
     $plataforms = Game::listAll(['limit' => 10, ....]); //recent plataforms added: limit=10&order_by=id,desc

     // return mounted json 
}

I'm currently using this approach. I've changed QueryBuilder.phpconstructor and simple changes in related classes.

This "breaking change" allow people to use your lib simple changing $request parameter to $request->all() :

new QueryBuilder(new User(), $request->all()))->build()->paginate();

Or in other custom scenario:

$params = []
new QueryBuilder(new User(), $params))->build()->paginate();

This was referenced Jan 4, 2017
@robsontenorio
Copy link
Author

robsontenorio commented Jan 4, 2017

QueryBuilder -> construct

public function __construct(Model $model, array $params = []) {
....
$this->uriParser = new UriParser($params);
....

UriParser -> construct

public function __construct(array $params = []) {
....
$this->uri = (count($params) > 0) ? '?' . http_build_query($params) : NULL;
....

@selahattinunlu
Copy link
Owner

@robsontenorio I commented to pull request. (#19) Please check it :)

selahattinunlu added a commit that referenced this issue Jun 13, 2017
@selahattinunlu
Copy link
Owner

selahattinunlu commented Jun 13, 2017

@ili5 @robsontenorio

I created different solution. You can check it from here 2a85dea

I will documented it.

I hope you like new solution :)

By the way thanks for idea @ili5 and @robsontenorio

Shortly you can use it like this:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Unlu\Laravel\Api\QueryBuilder;
use Unlu\Laravel\Api\RequestCreator;
use App\User;

class UsersController extends Controller
{
    public function index()
    {
        $request = RequestCreator::createWithParameters([
            'name' => 'selahattin',
            'email' => '!=blabla@example.com'
        ]);

        $qBuilder = new QueryBuilder(new User, $request);

        return response()->json([
            'data' => $qBuilder->build()->get()
        ]);
    }
}

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants