Add stateless API starter kit#78
Conversation
41c3dcd to
c73b048
Compare
21fbabe to
c45c6d6
Compare
joetannenbaum
left a comment
There was a problem hiding this comment.
This is looking really good! Just a couple of notes.
|
|
||
| event(new Registered($user)); | ||
|
|
||
| return response()->json([ |
There was a problem hiding this comment.
Why aren't we returning a user resource here along with the token?
There was a problem hiding this comment.
I don't think that's needed, TBH.
We already have the /me endpoint for getting the user info.
There was a problem hiding this comment.
Hm, not sure I agree here. I can get on board with that for login, but for register why don't we just do something like this? Reduces round trips and gives the client the information they definitely need anyway.
(new UserResource($user))
->additional(['token' => $token])
->response()
->setStatusCode(Response::HTTP_CREATED);| ); | ||
|
|
||
| if ($user->hasVerifiedEmail()) { | ||
| return response()->json(['message' => __('Email already verified.')]); |
There was a problem hiding this comment.
Might be overkill, but do we want to macro message, successMessage, etc? Or too much?
There was a problem hiding this comment.
That might be a good idea.
I'll try it out so we can check how it will look like
There was a problem hiding this comment.
Hey @joetannenbaum
I think this is a good idea to extract into a helper, because it's something that can be heavily used in the codebase when starting to implement something with the Starter Kit, however, I think the macro is not the best solution. Because it can be a little confusing, and depending on what devs are using, they may not even get autocomplete for it.
I think we can do it in either of these ways:
- A response class implementing the
Illuminate\Contracts\Support\Responsableinterface - A trait -
HasApiResponses(or something similar) - with a methodmessageResponse(or something similar)
There was a problem hiding this comment.
Let's go with response class, makes for better extendibility.
| ]); | ||
| } | ||
|
|
||
| $token = $user->createToken('auth')->plainTextToken; |
There was a problem hiding this comment.
Do we want to give them the opportunity to name this in case they want to list tokens and identify them? Like an optional device_name field with the auth fallback value?
There was a problem hiding this comment.
By default, I think we can use this auth, and if people need they can extend it, what do you think?
There was a problem hiding this comment.
I dunno, seems pretty cheap to just do something like $request->string('device_name', 'auth'), why not?
c45c6d6 to
1260ab6
Compare
joetannenbaum
left a comment
There was a problem hiding this comment.
Added some responses to our current conversations.
Two additional things:
- We're mixing
JsonApiResourceand flat JSON responses, feels funny. We should go one or the other, yeah? Or, probably worse idea, allow the user to choose the format at installation time? - I think we talked about it and may have tabled it, but should we offer/scaffold anything around versioning in the kit?
dffbd39 to
153376d
Compare
a9f93c2 to
b4554a3
Compare
|
Exciting to see this as ready for review! ⭐ |
|
@RasmusPJustesen we're getting there! 🚀 |
BuildCommand, StarterKit enum, kit-manifest, check-kits, and kit-helpers updated to handle the new API kit. GitHub Actions workflows include the API variant in test and push matrices. README, CLAUDE.md, AGENTS.md, and SKILL.md reflect the new variant count (22) and --api flag.
Ships kits/API/Base, a stateless JSON API layer on top of Shared/Blank and Shared/Base. - Sanctum auth flow: register, login (rate limited), logout, current user - Profile and password updates as PATCH endpoints - Email verification with signed URLs and resend notification - JSON:API-style responses via a single UserResource - Scribe-driven docs configured entirely with PHP attributes - Response messages wrapped in __() so kits can localize them - Feature tests covering every endpoint plus Unit/Feature ExampleTests
- Add DELETE /user account deletion endpoint requiring the current password; tokens and user are removed inside a transaction - Add POST /token/refresh to rotate the current Sanctum token - Drop the /api URL prefix and redirect / to /up - Give every API route an explicit name and migrate tests to route() helpers - Wrap register and refresh DB writes in transactions; dispatch the Registered event after commit
Mirror the Inertia/Livewire Fortify kits: unverified users can still log in, view, and update their profile (to fix their email), but cannot delete their account or change their password. Adds two regression tests that skip when MustVerifyEmail is not enabled.
Without this file, the watcher in orchestrator/scripts/watch.js had no source of vendor/node_modules ignore patterns for the API layer stack and would sync build/vendor/** back into kits/API/Base on live change events.
Allow signed API verification links to succeed without a bearer token while keeping API-only matrix runs separate from Fortify variants. Made-with: Cursor
- Throttle the register endpoint at 5/min to match login - Validate the verify-email hash before exposing already-verified state, closing the unauthenticated account-probe vector - Preserve the original token name and abilities on refresh instead of resetting both to 'auth' and ['*'] - Use fluent Rule::unique(User::class) in RegisterRequest for parity with ProfileUpdateRequest - Use Tests\TestCase in tests/Unit/ExampleTest so the unit suite uses the kit's bootstrap
b4554a3 to
c060ddc
Compare
Overview
Maestro ships starter kits for every flavor of Laravel app, but there was no option for teams building a pure JSON API. This adds a new API variant so backend-only projects can start from the same orchestrated foundation as the Inertia and Livewire kits.
About the Kit
The kit is stateless and built on Sanctum, with endpoints for register, login, logout, current user, profile and password updates, email verification, token refresh, and account deletion. It also uses JSON:API resources.
Scramble generates the API docs and serves them at
/docsusing Scalar. Account deletion and password updates are gated behind theverifiedmiddleware to match the Fortify kits, while profile edits stay open so unverified users can fix a bad email.Orchestrator Updates
Orchestrator support comes along with it:
BuildCommand, theStarterKitenum, the kit manifest, and the check/kit helpers all learn about the new variant, and CI plus the push workflow now include API in the matrix.The README,
CLAUDE.md,AGENTS.md, andSKILL.mdwere updated to reflect the new variant count (22) and the--apiflag.