Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Origami Api Sdk Laravel Package

origami-mp/origami-api-sdk

origami-mp/origami-api-sdk is a PHP SDK for the Origami API, providing a convenient client to streamline authentication and endpoint requests. It helps Laravel and PHP developers integrate with Origami services faster with less boilerplate and more consistent API handling.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and confirm what you actually got.

composer require origami-mp/origami-api-sdk

Before writing a line of app code, read three things in the vendor tree:

  • composer.json — the require block (is illuminate/support there, or is it framework-agnostic PHP?), the autoload PSR-4 root, and any extra.laravel.providers / extra.laravel.aliases. If there is no service provider, there is no config file to publish and you wire everything yourself.
  • src/ — the layout is the documentation here. Expect Data, Guest, Oauth API repositories, a ParamBags (or similar) tree, DTOs, client repositories, Exceptions, Enums, Helpers.
  • tests/ — the single best source of usage examples. In this package the conventions doc explicitly tells contributors to "refer to real code… by class name", which means the tests are the reference implementation for every repository method, param bag and DTO.

2. Configure credentials once.

Given the SDK splits Guest (public) from Data (authenticated) and Oauth, expect at minimum a base URL and an API key/token. If a config file exists:

php artisan vendor:publish --tag=origami-api-config
ORIGAMI_API_URL=https://api.example.test
ORIGAMI_API_KEY=...

If it does not, register a singleton in a AppServiceProvider so you inject a configured client repository rather than newing it up in controllers:

$this->app->singleton(OrigamiClientRepository::class, fn () => new OrigamiClientRepository(
    baseUrl: config('services.origami.url'),
    apiKey: config('services.origami.key'),
));

3. First use case: one read, end to end.

Start with a Guest repository method — it removes auth from the equation and lets you confirm transport, DTO hydration and exception mapping in one call:

// illustrative shape; check the real signatures in src/ and tests/
$params = new ListingIndexParamBag();
$params->setInclude(['seller', 'photos']);
$params->setPage(1);

try {
    $listing = $guestRepository->getListing($id, $params); // returns a DTO
    return response()->json($listing->toArray());
} catch (OrigamiApiSdkException $e) {
    report($e);
    abort(502, 'Upstream unavailable');
}

Then repeat with a Data repository to confirm the key is being sent, and an Oauth one only when you actually have a user token flow.

Pattern Patterns

Inject repositories, never construct them in controllers. Each API repository method is "HTTP call in, DTO out", which makes it a clean dependency. Constructor-inject into a thin application service, and let the controller stay dumb:

final class ListingService
{
    public function __construct(private ListingApiRepository $listings) {}

    public function detail(int $id): ListingData
    {
        return $this->listings->get($id, (new ListingParamBag())->setInclude(['seller']));
    }
}

Treat DTOs as your read model, not as entities. They hydrate from the API response and validate it, so they are safe to hand to a Blade view, an API Resource, or Inertia props via toArray(). Do not leak them into Eloquent relationships or ->save() anything from them — they are response-shaped, not persistence-shaped.

Param bags are input, DTOs are output, and they are not symmetric. Build a param bag per request, compose nested bags for sub-resources, and keep the bag immutable-ish per call site (don't share one instance across calls and mutate it — mutation bugs here are silent, since the bag carries no validation).

Writes go through the same seam but behind a queue. Because every mutation is one repository method, wrapping it in a job is trivial and gives you retries plus a natural place to log the OrigamiApiSdkException family instead of surfacing it to the user.

Map exception families to HTTP status in one place. The SDK groups API exceptions into families, and an API error picks a specific one. Register a handler/renderable that translates SDK exceptions into 4xx/5xx once, rather than try/catching in every controller. Anything unmapped → 502 with the upstream error logged, never echoed.

Test at the seam, not through it. Either fake the HTTP layer (Http::fake() if the client repository is built on the Laravel HTTP client) or bind a stub client repository in the container. The client repositories exist precisely so HTTP can be swapped — that is the extension point the SDK authors designed for. Write one contract test per repository method against recorded/known fixtures and let the rest of your suite hit the stub.

Ask for includes explicitly. Related data is not returned unless requested through the include rule. In a list endpoint, requesting includes you don't render is the most common cause of slow pages; requesting none and then calling $dto->seller->name is the most common cause of nulls.

Gotchas and Tips

  • There is no consumer-facing README. The only documentation is an internal conventions skill written for people contributing to the SDK, not for people using it. Nothing in it tells you how to install or configure the package. Budget an hour to read src/ and tests/ before estimating any work.
  • Zero stars, zero dependents. There is no Stack Overflow corpus, no blog posts, no third-party examples. Pin the version in composer.json ("origami-mp/origami-api-sdk": "1.*", not ^), and wrap it in your own App\Services\Origami\* layer so an upstream breaking change is a one-file fix.
  • Param bags carry no validation rules — deliberately. Validate with Form Requests on your side. Do not add rules to a bag; the convention forbids it and a PR doing so will be rejected.
  • Every property has a declared API key and often a custom cast. When you add a parameter, the name you send is defined explicitly on the property. Guessing the wire name from the property name will produce silently ignored parameters.
  • Nested lists need an explicit init<Property>() call on the DTO before they hydrate. If a collection comes back empty when the API clearly returned items, this is your bug, not theirs.
  • toArray() is overridden last in every DTO and includes commented-out entries for fields that aren't always present. Don't "clean up" those comments — they document the include contract. If a key is missing from your JSON, check whether the include was requested first.
  • Style is enforced by Pint with the Laravel preset, plus SDK-specific rules: braces around every interpolated variable ("sellers/{$id}"), array spread instead of array_merge()/+, and a fixed element order (traits, cases, constants, properties, constructor, setUp(), then public/protected/private, toArray() last). Run vendor/bin/pint with the package's pint.json if you patch the SDK in a fork, or your diff will be all whitespace.
  • Enums double as validation. Param bags reuse their DTO's enum, and the same enum goes into Rule::enum() in your Form Request — one source of truth for allowed values. Adding a case to a shared enum touches every place it's used; grep before you add.
  • Extending the SDK is a documented ritual, not free-form. New cross-cutting behaviour = a trait + its <Name>Contract; new transport behaviour = override a hook on a client repository; new helper = static methods, no business logic, with tests. A change introducing a genuinely new pattern is expected to update the skill file in the same PR — so if the conventions don't cover your case, follow the nearest existing pattern and say so in the PR rather than inventing one.
  • Debugging tip: when a call fails opaquely, drop to the client repository and log the raw response before DTO hydration. DTO validation errors are thrown when the payload doesn't match the expected shape, and the exception message is about the field, not about the HTTP call — which reads confusingly until you've seen it once.
  • Check the sibling origami_api repo when a response shape surprises you. The SDK mirrors the API's actual format, and the API repo is the authority on what a field really contains.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo