dreamfactory/df-rws
DreamFactory Remote Web Services (df-rws) is a connector that lets you register external REST APIs as managed services in DreamFactory, adding authentication, role-based access control, rate limiting, and unified API documentation without custom code.
dreamfactory/df-rws is the Remote Web Service (RWS) connector module for DreamFactory — the piece that lets the platform expose an external REST or SOAP endpoint as a governed API (auth, roles, rate limits, logging, OpenAPI docs) without writing a controller. Treat it as a platform plugin, not a normal Laravel library: you don't use it in your app's controllers, you install it into a DreamFactory instance (which is itself a Laravel app) and configure it.
Minimal steps
df-core version, or the service type won't register.composer require dreamfactory/df-rws
php artisan list for the dreamfactory:/df: namespace, then run the refresh and migrate commands).composer.json's extra.dreamfactory block and the module's ServiceProvider.GET /api/v2/{api_name}/... with an API key.Where to look first
composer.json → extra.dreamfactory (how the platform discovers it)src/ → the service provider, the service-type handler, and the request/response plumbingconfig/ and database/migrations/ → the defaults and the service table shape your config lands inFirst use case. Wrap a legacy internal SOAP endpoint (or a third-party REST API your mobile app shouldn't hold keys for) so clients and LLM tool-callers hit one authenticated, role-scoped, rate-limited DreamFactory URL. That is the whole value proposition: credentials and policy stay server-side, clients get a uniform API.
Config-as-code, not click-ops. Service definitions live in the database, so the UI is the easy path and the wrong long-term one. Keep the service payload as JSON in your repo and apply it on deploy:
{
"name": "shipping_quotes",
"label": "Shipping Quotes",
"type": "rws",
"is_active": true,
"config": {
"base_url": "https://legacy.internal/shipping",
"headers": { "Accept": "application/json" },
"parameters": {},
"username": "",
"password": ""
}
}
Then POST /api/v2/system/service from a seed/deploy script (or the platform's package-import artisan command). This gives you diffs, review, and rollback.
Passthrough is the default contract. The service maps GET /api/v2/shipping_quotes/rates?zip=... onto the upstream path. Don't expect field renaming, pagination normalization, or error translation for free — those go in server-side scripts (pre/post process) attached to the service, where you can reshape payloads, strip internal fields, and map upstream 4xx into sane client errors.
Auth delegation. The platform handles API keys, JWT, and session auth for your callers. Upstream credentials belong in the service config or, better, pulled from env/user_config so they never sit in a git-tracked JSON. Per-user upstream credentials (each caller supplies their own legacy login) are a legitimate pattern here — store them in the user's config and reference them in the script layer.
Consuming it from Laravel. Your Laravel app is just another client:
$quotes = Http::withToken(config('services.dreamfactory.token'))
->baseUrl(config('services.dreamfactory.url').'/api/v2')
->get('shipping_quotes/rates', ['zip' => $zip])
->throw()
->json();
LLM / tool-calling. This is the package's modern niche: expose the wrapped service through DreamFactory's OpenAPI generation and hand that spec to a local model as function definitions. You get tool access to a data source with the platform's role scoping acting as the guardrail — far safer than giving the model raw HTTP egress.
Policy layer. Create one role per consumer (mobile app, internal dashboard, LLM agent), attach only the services each needs, and set per-role rate limits. Use lookup keys rather than sharing a single admin key.
Testing. Seed a service pointing at a stub (WireMock/httpbin) in your test environment and write Pest tests against the DreamFactory API with a scoped key. You are testing configuration and scripts, not PHP units — that's the correct shape here.
df-core/platform major version makes the service type vanish silently. Pin both, and bump them together.base_url is admin-controlled, but path/verb forwarding plus scripted parameters can be abused if you hand broad roles to untrusted consumers. Restrict verbs and paths per role.How can I help you explore Laravel packages today?