PHPackages                             hacp0012/quest - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. hacp0012/quest

ActiveLibrary

hacp0012/quest
==============

Express router for accessing methods

1.3.10(11mo ago)026MITPHPPHP &gt;=8.0CI passing

Since Sep 23Pushed 11mo ago1 watchersCompare

[ Source](https://github.com/hacp0012/Quest)[ Packagist](https://packagist.org/packages/hacp0012/quest)[ RSS](/packages/hacp0012-quest/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)DependenciesVersions (12)Used By (0)

[![Logo](./doc/assets/quest.png)](./doc/assets/quest.png)

Quest
=====

[](#quest)

Access resources directly without defining routes, thanks to PHP attributes.

[**Please visite online doc**](https://hacp0012.github.io/Quest/)

*[▶️ French Readme here](./fr.md)*

---

- [Introduction](#introdiction)
- [Instalation](#installation)
- [Usage](#usage)
    - [The service container](#service_container)
- [Runnig operation](#fonctionement)
- [API reference](#api_ref)
- [FAQ](#faq)

🪬Introdiction
-------------

[](#introdiction)

Quest, the **Master Guru** which simplifies your quest, it gives you a short route to follow to reach your goal (resource).

I know, you don't need to lie to me 🤥, you have remembered when you are brainstorming to implement a functionality or recover resources and ask you: but ... **how do I will organize my Routes?**

The question of the routes, I do not hide you, me, it fucks the laziness. Because I must be defined a road for any call and suddenly I find myself with many of the defined Routes.

I know, it's not perfect, and neither is **Quest**, but... it will make your job a lot easier and eliminates all that mental overload, useful but boring.

✨ Installation
--------------

[](#-installation)

### Prerequisites

[](#prerequisites)

- PHP 8.0+
- Laravel 9.x+
- Have already made use of the Facade Route. Ex: `Route::get('route/to/x/{param}', fn(string $param) => X)`

### Install Quest from composer

[](#install-quest-from-composer)

```
composer require hacp0012/quest
```

### Publish the config files

[](#publish-the-config-files)

Quest needs a few files to work properly.

```
php artisan vendor:publish --tag=quest
```

**The file route quest.php**

is a base file that can be useful to you to register your classes. Because the classes registered in this list are public of the second level, because they have a priority that comes after the list passed in your route `Quest:spaw(routes: [])`

> These references are accessible from all requests.

**Experimental**: It is now possible to pass directories, whose base starts from the base directory (of the project) of Laraval. Very useful if you do not want to specify each time a class that contains your references, You just have to specify a directory or several directories.

> Provided that the punched method is in a class and the class is in a namespace. *Only the first class is considered in a .php file*.

This file is generated automatically but you can generate it manually.

**The config quest.php**

Contains some settings you can apply if you have made patterns in your project's bootstrap/provider.php for custom targeting of your route files (/routes/web.php or /routes/api.php).

Because Reference Tracker needs to know your targets to track your referenced (punched) methods.

> To publish the configuration files type the command php artisan vendor:publish

This will create the file `config/quest.php` (which contains some configuration bits) and the global quest routing file in `routes/quest.php`.

*Manually, you can publish the config files like this php artisan quest:publish in the configs/ and routes/ directory manually.*

🏳️ How is it useful to me?
--------------------------

[](#️-how-is-it-useful-to-me)

Quest allows you to access resources or send your resources directly without worrying about Routes. You just need to set Reference Flags or Reference Marks using PHP attributes on your class methods and call 🤙 these methods directly, with the same parameters as those of the method.

*Don't worry, you just need to respect the same types of parameters that you had defined on your method.*

Let's take for example, in a case where you are designing an application and reach a certain level where your application will need to retrieve an up-to-date list of telephone codes. You just have to create a method in a class, reference it and call it; without worrying about creating a route for it.

```
class PhoneHandler
{
  #[QuestSpaw(ref: 'r84d2S1tM')]
  function getCodes(): array
  {
    //...
  }
}
```

```
// And call it as this :
axios.get('https://myhost.com/r84d2S1tM');
```

An other exemple :

```
#[QuestSpaw(ref: 'my quest flag ID', filePocket: 'guidPicture')]
function yogaStage(int $moon, int $sunRise, UploadedFile $guidPicture = null): int
{
  # $guidPicture --> Illuminate\Http\UploadedFile

  return $moon + $sunRise;
}
```

```
// So the call will simply be like this:

// Client code :
dio.post("/quest/my quest flag ID", data: {'moon': 2, 'sunRise': 7});
```

Note that Quest takes care of passing parameters to your method. (And you can even pass it a file) as parameters, just give the parameter name to your file. (but you have to report it in filePocket)

🚧 How Quest works
-----------------

[](#-how-quest-works)

Quest is based on PHP attributes. It goes through all your references and creates a registry of the methods you have marked. A method is marked by a reference key that serves as a reference point for quest to call your method.

To create a reference:

```
#[QuestSpaw(ref: 'reference.key')]
functiton gong(): array
```

🧩 Usage
-------

[](#-usage)

Let's start by defining our route with Quest:

```
# In your route file
use Hacp0012\Quest\Quest;

Route::get(uri: '/', action: fn() => view('home')); // Exemple ...

$routes = [
  Forest::class,
  # Or specifie a directory:
  // 'app/demo',
];

# Or it can be only the class name.
$routes = Forest::class; // Or directory.

Quest::spawn(uri: 'quest', routes: $routes)->name('my.quest');

# Or

Quest::spaw(uri: 'my/forest', [Forest::class, 'RrOWXRfKOjauvSpc7y']);
// For direct call.
// Note method name, this is `spaw`.
```

> **`Hacp0012\Quest`** is the main namespace. Contains the `Quest()` class and the `QuestRouter()` class and the `QuestSpawMethod` enum. Then there is the namespace **`Hacp0012\Quest\Attributes`**, which contains the Quest attributes. Such as `QuestSpaw()` and `QuestSpawClass()`.

You can add middlewares and such because Quest's static `spawn` function returns an object of type `Illuminate\Routing\Route` so it supports all other methods of the Route facade.

> Note that the `Forest` class has been added to the list of routes in the `spaw(..., routes: [Forest::class])` method.

Let's now define our Forest class which will contain our methods referenced by spaw. *punched*.

```
// In your class
class Forest
{
  #[QuestSpaw(ref:'NAhLlRZW3g3Fbh30dZ')]
  function tree(string $color): int
  {
    return $this->fruits();
  }

  function fruits(): int
  {
    return 18;
  }

  #[QuestSpaw(ref: 'RrOWXRfKOjauvSpc7y', method: QuestSpawMethod::GET, jsonResponse: false)]
  function displayAnApples(int $count): View
  {
    //...
  }
}
```

And that's it, now you can start calling your methods punched (referenced) by their reference key `ref: 'NAhLlRZW3g3Fbh30dZ'`.

Note that you can use any phrase as a reference. Although quest allows you to generate unique keys. You can use something like: *forest.app.tree.NAhLlRZW3g3Fbh30dZ*. [Or see the CLI command reference for more details](#ref_console)

As in this example above:

```
// Code client :
dio.get("/quest/NAhLlRZW3g3Fbh30dZ", data: {'color': 'green'});
```

```
// Or from your view blad file:

route('my.quest', ['quest_ref' => 'RrOWXRfKOjauvSpc7y', 'count' => 9]);
# It's simple when you have given a name to your route. `->name('quest')`.
```

*`quest_ref` is the parameter key of the route generated by Quest. The kind of parameters that we pass in the url: [https://moonsite.com/my/quest/{quest\_ref}](https://moonsite.com/my/quest/%7Bquest_ref%7D)*

🔖 There is another way to call Quest. That is to pass QuestRouter and create a router object, like this:

```
Route::post('quest/{ref}', function(string $ref) {
  $quest = new QuestRouter(questRef: $ref, routes: [QuestTest::class]);

  return $quest->spawn();
});
```

Or

```
Route::post('quest/{ref}', function(string $ref) {
  $quest = new Quest;

  $data = $quest->router(questId: $ref, classes: [QuestTest::class]);

  return $data;
});
```

⚠️ Even though this is not the cleanest method, I advise you not to use it because it can give you weird return types that even Laravel's `Service container` won't be able to interpret.

### Service container

[](#service-container)

Laravel provides an automatic dependency injection system that it calls Service Container. It is able to construct an object that you have declared as a parameter.

Take this as a reminder:

```
Route::get('/', function(Request $request, int $number) {
  // The container service automatically builds $request for you.
});
```

Well Quest can't spoil this happiness. Quest also resolves your objects declared in the parameters. In any case feel free to do what you want.

🪄 *Try and you will know.* 🧙‍♂️

👽 CLI Commandes
---------------

[](#-cli-commandes)

> `php artisan quest:ref [--list [--no-table] [--index=n]] [--generate=n] [--track='']` [see in doc.](./doc/refs/commands.md)

> `php artisan quest:generate-ref [36] [--uuid]`

Generate a reference key. But this does not prevent you from taking any text for reference. This is just a help, to allow you to do something unique.

*If you add the `--uuid` option, it will generate a UUID key and ignore the length you specified. UUIDs are 36 characters long (they are unique anyway)*

By default the command generates 36 random characters.

php artisan quest:generate-ref

[![Generated ref code](./doc/assets/generated_ref.png)](./doc/assets/generated_ref.png)

> `php artisan quest:track-ref [ref-id]`

Track the reference of a pointed method (spawed)

Among the good things, there is the ref tracker. This tracker is great, it allows you to find yourself more easily and find the implementation of your method.

php artisan quest:track-ref RrOWXRfKOjauvSpc7y

[![Tracked reference result](./doc/assets/ref.png)](./doc/assets/ref.png)

Because let's be serious, the reference key system can be a little more constipating when you don't have a very solid architecture or when you are a beginner. This is why I advise you not to rely only on the keys generated by the `quest:generate-ref` command, get into the habit of adding a few words called **human readable**. Ex. 'my.forest.trees.meXRQbm0WQP6ZpAN5U'

To check the quest version:

> `php artisan about`

*This is an internal command of Laravel*

🔆 Api reference
---------------

[](#-api-reference)

- [Quest Attributs](./doc/refs/attributs.md)
- [Quest class](./doc/refs/quest.md)
- [Quest response](./doc/refs/response.md)
- [Quest Router](./doc/refs/quester_router.md)
- [CLI Commands](./doc/refs/commands.md)

Best practices
--------------

[](#best-practices)

### The type of return in comment

[](#the-type-of-return-in-comment)

Let's take this example:

```
/** @return stdClass {state:UPDATED|FAILED} */
#[QuestSpaw(ref: 'com.update.text.628L7cLg1RGTvaxkgg')]
function updateText(string $com_id, string $title, string $text, string $status): stdClass
{
  $return = new stdClass;

  $state = false;

  // ...

  $return->state = $state ? 'UPDATED' : 'FAILED';

  return $return;
}
```

Please specify the return type and details about it, because the tracker returns the PHP-Doc comments of the method. This will help you to have a direct idea of ​​what is returned by the call.

[![Screen shot](./doc/assets/2024-09-09-174755.png)](./doc/assets/2024-09-09-174755.png)

Things to add
-------------

[](#things-to-add)

- Temporary routes.

FAQ
---

[](#faq)

### How can I do my `request` validations ?

[](#how-can-i-do-my-request-validations-)

First of all the method parameters are also another type of validation but low level. You can retrieve all your `request parameters` via the `Request` object like this:

```
function myMethod(Request $request, array $myQueryParams)
{
  $validateds = $request->validate([...], [...]);

  $validateds = request()->validate(...);

  # ...
}
```

> By default, quest supports some basic (native) types `['bool', 'int', 'float', 'string', 'null', 'array', 'mixed', UploadedFile::class]` and the one you linked in Service Container via Provider. Other types are not supported. The reason is that over HTTP(S) we don't often transfer objects. It's often text and often formatted in JSON. So the basic (native) types are often the same types that the JSON annotation supports.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance51

Moderate activity, may be stable

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~25 days

Recently: every ~41 days

Total

11

Last Release

344d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d33396b0fce07609eff3d094ffa67751ca0fc0800c1e412b12fe28d398324f9f?d=identicon)[hacp0012](/maintainers/hacp0012)

---

Top Contributors

[![hacp0012](https://avatars.githubusercontent.com/u/34531182?v=4)](https://github.com/hacp0012 "hacp0012 (56 commits)")

---

Tags

attributeattributeslaravelphprequestrouterroutesrouting

### Embed Badge

![Health badge](/badges/hacp0012-quest/health.svg)

```
[![Health](https://phpackages.com/badges/hacp0012-quest/health.svg)](https://phpackages.com/packages/hacp0012-quest)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
