Extending the record count that Mailcoach's API will fetch
Bob Murdoch • July 14, 2024
mailcoachMailcoach comes with a great API that allows you to interact with it from remote applications, but you may find one pain point if you're trying to work with whole resource lists vs. targeting a single entity.
At the time of writing, the API has a rate limit that is not configurable.
Normally their allowance would be sufficient, but if you query some resources like all subscribers on a list, again at the time of writing this, you will get paginated results 25 at a time. So your ability to retrieve the details of a large list 25 subscribers at a time will be quickly hindered by that rate limit.
One solution I've found involves 2 steps. The following is an example for fetching subscribers, but the same can be applied to models for other resources:
- After digging down in my IDE on the eloquent paginate method, I was able to find this number is actually defined in a function called getPerPage on the abstract Model class that all models extend. So start by taking a look at your Mailcoach config file for the spot to override models. Create your own subscriber model that extends the Mailcoach subscriber model and simply override that function. In this example, we're instructing Laravel to honor the per_page argument if sent (this is the default behavior), or if not present in the request set to 1,000. The underscore is a handy feature for making large numbers more readable since PHP 7.4.
// app/Models/YourSubscriberModel.php
public function getPerPage()
{
return request('per_page', 1_000);
}
...
- While this fixes the pagination call, it breaks Mailcoach's API authorization for the model you're overriding. To fix this, head over to the boot function in your AppService provider and instruct Laravel to gate your new model with Spatie's policy for the overriden model. E.g.
// app/Providers/AppServiceProvider.php
/**
* Bootstrap any application services.
*/
public function boot(): void
{
...
// add this in:
\Illuminate\Support\Facades\Gate::policy(
\App\Models\YourSubscriberModel::class,
\Path\To\Spatie\SubscriberPolicy::class
);
}
...
being sure to fix the Spatie path to the real one (not sure how much they want me to show here since it is closed source).
With those 2 changes you should be able to have full control of what you fetch via the API.