Every app we build starts with the bootstrap request, GET /api/bootstrap. It returns the data the whole app shares: settings, code lists, translations, the logged user and their data. Each method of the AppRequest class is a section, and each section lands in the Pinia store with the same id. The frontend fetches it on start and refreshes it in the background, see App boot and auth. The same sections are returned by other endpoints after a change, see Sharing data with the frontend. ?only=locale,auth returns only the given sections; without it the request returns all sections of a guest or of a logged user.

Shared PHP implementation

In PHP helpers 2.0, AdminHelpers\Utilities\BootstrapRequest extends Admin\Core\Bootstrap\BootstrapRequest from crudadmin/framework 6. The framework owns section composition (get, guest, authenticated, all, only) and caching. Helpers adds the project client, token, auth() response and onClient() hook. Existing AppRequest subclasses keep their imports. The administration uses its own Admin\Bootstrap\AdminBootstrapRequest, built on the same framework base with admin session and verification rules. Its endpoint is /admin/api/bootstrap; it does not reuse your application’s /api/bootstrap. Every public method is a section by default. Opt in to a whitelist to keep public helpers out of ?only=: list the sections in protected $sections = ['locale', 'app', ...], or mark them with the Admin\Core\Bootstrap\Attributes\BootstrapSection attribute. With either, only the base sections (get, guest, authenticated, and auth in helpers), the listed and the marked methods are sections. Override canLoadSection($method) for other rules. A guest gets a 403 for a section of the $authenticated property, and for a section requested directly which only an overridden authenticated() composes (not get() or guest()). Sections composed by get(), guest() or another loaded section are allowed. A guest never gets authenticated. Configure section caches with ['minutage' => 5] or a number of minutes; duration is an alias of minutage. Array entries default to 60 minutes. Cache keys contain the bootstrap class basename, locale and section name, plus an optional key callback result. User-dependent sections need an appropriate key or must remain uncached. Invalidate a cached section with forgetCache($section, $key = null, $locale = null), e.g. from a model observer: AppRequest::forgetCache('locale').
  • Without $key and $locale, every variant of the section (all locales, all keys) is invalidated by raising its version. Old entries expire on their own.
  • With $key, the entries of that key value are forgotten in $locale, or in every locale (cacheLocales(): application locales and CrudAdmin languages).
  • A $locale alone on a section with a key callback invalidates the whole section.
The cache is per class: call forgetCache() on the class which serves the section.

Configuration

Register the route of crudadmin/helpers and point the config to your class. The route answers ANY /api/bootstrap?only=a,b with autoAjax()->store(...), and bootstrapRequest(), BootstrapResolver::make() and the bootstrap login response all resolve your AppRequest through the config.
routes/api.php
config/admin_helpers.php
The route sits behind an optional authentication middleware, so a guest gets the guest sections and a valid token the authenticated ones. Older projects have their own controller doing the same:
app/Http/Controllers/BootstrapController.php

Several applications

Projects with several apps (customer, courier…) select the request class by the app-type header. Map the types in the helpers config; an unknown or missing type uses the default class.
config/admin_helpers.php
The frontend of each app sends its type, in Nuxt through crudadmin.platform.type. The route registered by BootstrapResolver::routes() selects the class by it. BootstrapResolver::make() and the bootstrapRequest() function return a new instance of the selected class, BootstrapResolver::getClass() its name.

AppRequest class

This class is used to render all data returned from bootstrap request during GET response. You can add as many methods as you need, and split them between guests and authorized users.
app/Utilities/Bootstrap/AppRequest.php
We are using singular forms of method naming. Same in Pinia stores.

Facade

You can create shortcut to you AppRequest accordingly to your needs. Helpful if you have multiple bootstrap classes in your project.
config/app.php

Response and structure

Each section is a key of store, and useResponse() writes it into the Pinia store with the same id.
The data is wrapped in the store object only when store is true in the autoajax config. Otherwise it is merged into data and never reaches the stores.
config/autoajax.php