Releases: dskripchenko/laravel-api-idea
Release list
1.0.0 — one API line, everything the endpoint offers
Eleven releases of finding out what this plugin is for, and the answer settled:
it makes the two things the package keeps in separate files — the docblock
markup and the route map — visible as one endpoint, while you type.
Nothing in the public surface is expected to change now, which is what the
number says. The markup grammar, the inspections and their ids, the settings
keys and the API line are what they will be.
Added
-
One
APIline above each routed method, with everything the endpoint
offers under it. Its page in the reference documentation, and the endpoint
itself as a request in each formatapi:exportproduces — Bruno, cURL, HTTP
Client, Postman, Markdown. The gutter icon on the route map's action key opens
the same list.Before this the two halves lived apart: a link that opened documentation, and
an export buried in the editor's context menu where nobody found it. One
subject, one place.
Changed
-
The line appears when either half is possible, not only both. It used to
need a documentation address, so a project withoutAPP_URLgot no line — and
with it no export, which never needed an address in the first place. The list
now holds what is actually available, and an item that is missing is the answer
to why: a version a module assembles at runtime cannot be addressed, a version
inhidden_versionsis never loaded by the page, a project withoutartisan
has nothing to export with. -
The label is
APIrather thanAPI docs: v1.GET. It sits above every
routed method in a controller, and forty repetitions of a long label read as
noise. What it leads to is one click away, and in the tooltip without one.
0.9.1 — the documentation link reads instead of pointing
Changed
-
The documentation link above the controller method, instead of a second
gutter icon. Beside the route arrow it read as clutter rather than as two
facts — and an icon can only say "there is something here", while a line can
say what:API docs: integration.GET. It sits where the IDE already puts
statements about a declaration, next to who wrote it and how many usages it
has, and it can be switched off on its own under Settings | Editor | Inlay
Hints | Code Vision.The route map keeps its icon. There the trade goes the other way round:
getMethods()is an array of action keys and nothing else, so a hint line
above each one would double the height of the thing being read.
0.9.0 — exporting the endpoint under the caret
Added
-
Export the endpoint under the caret as a request. Right-click a controller
method or an action in the route map, pick a format — Bruno, cURL, HTTP
Client, Postman, Markdown — and the request opens in a scratch file, ready to
send, edit, or save into wherever the collection lives.The producing is the application's: this runs
api:export --endpoint, the
same ruleapi:lintestablished. The docblock-to-OpenAPI pipeline belongs to
the package, and a Kotlin copy of it would be a second truth that starts
drifting the day either side is touched.What the plugin adds is the part that was tedious: knowing which endpoint is
meant. Working out that the method under the caret is routed as
v1.order.create— by which version, under which controller key — is exactly
the lookup nobody wants to do in a terminal, and the reason the export was
mostly unused.The same thing is in the endpoint list's context menu. Requires
dskripchenko/laravel-api5.9 or newer, where--endpointand--stdout
exist.
0.8.0 — the endpoint's own page in the reference
Added
-
A way into the API reference from the code that produces it. The
documentation page can address a single operation, and building that address
by hand is enough work that nobody does it: the version comes from the module,
the path from the URI pattern, the tag from the controller key, the HTTP
method from the route map, and the host from the environment. A gutter icon on
the action ingetMethods()and on the controller method it routes now opens
exactly that operation.The icon appears only where the link will work. A version a module assembles
at runtime cannot be named from the source, and a version inhidden_versions
is never loaded by the page — an anchor into it scrolls to nothing. Both cases
draw no icon, and the endpoint list's context menu explains which one it is.An action declaring two HTTP methods is two operations, and an Api class
exposed under two names is two endpoints; either way the click asks which.Requires
dskripchenko/laravel-api5.8 or newer, where the page is handed a
stable slug per version. Before that release the anchor was derived from the
first line of the Api class's docblock, and no link could be built from the
outside without reimplementing how that sentence is cleaned up. -
A second settings field: where the documentation is served from. Empty
meansAPP_URLfrom the project's.env, which is right whenever one reads
the documentation of the application one is running. Filling it in points the
links at a stand instead — an ordinary thing to want, and nothing in a
repository can express it.
Fixed
- The route map's
'method' => [...]is read. It was ignored entirely,
which nothing depended on until an endpoint's HTTP method became part of its
address.
0.7.0 — the version, and which PHP
Added
-
The endpoint list names the version. A line used to read
print-form.create → create()in an application where two versions declare
print-form, which is not an endpoint but an ambiguity: the version is the
first segment of the URL and the only thing telling the two apart.It reads
integration.print-form.create → create()now — the name the
package already registers the route under (api.{version}.{controller}.{action})
with its prefix dropped, so the same spelling works here, in the route list
and in a log. An Api class exposed under two versions produces two lines,
because two URLs are two endpoints however much code they share.It is read from the module's
getApiVersionList(), which is where the name
actually lives — the Api class itself has no idea what it is reached under.
Versions a module assembles at runtime, asAdminApiModuledoes for its
panels, cannot be read by anything static; those rows keep the old form
rather than showing a guessed name, because a column that is sometimes wrong
is worse than one that sometimes stops. -
The PHP interpreter can be set in Settings | Tools | Laravel API, and
api:lintruns with it.Searching the shell's PATH is right for a machine with one PHP and wrong for
every other: a version manager makes "the" interpreter a question about a
directory, and the wrong answer fails deep inside the application with a
syntax error in a vendored file. The IDE's own interpreter setting is not
readable — the PHP plugin does not publish that part of its configuration to
other plugins, which is why this is a setting here rather than a lookup.A configured path that does not exist, is a directory, or is not executable
is refused by name instead of quietly falling back to some other PHP. Left
empty, the search behaves exactly as before, and the settings page shows what
it currently finds, with the version, so the field is not a guess either.
0.6.2 — a clean compatibility check
Fixed
-
The compatibility check on the plugin page stopped reporting warnings.
Every upload since 0.3.0 carried them: six usages of internal API, six of
experimental, four of deprecated — none of which appeared anywhere in the
source.They came from the compiler. Implementing a platform interface in Kotlin makes
it emit a delegating override for every default method that interface has —
getIcon,getAnchor,manage,isApplicable,isDoNotActivateOnStart— and
the verifier reads a generated bridge exactly as it reads a hand-written call.
Compiling with-jvm-default=no-compatibilityleaves the class with the two
methods it actually declares. -
The two genuine ones are gone too. Navigation from a double-click in the
endpoint list and in the lint panel resolved its target through
ReadAction.compute, deprecated in 2026.1, whose Kotlin replacement
runReadActionis deprecated as well. Both now take the non-blocking path the
list itself already used — which is not only current but better mannered:
resolving a method touches the index, and that is not work to do between two
mouse events.
Changed
- The verifier now fails the build on any of this, rather than reporting it
on a page nobody reads until a release is already out. Internal and
experimental API break without a deprecation cycle; deprecated API is included
because the only two the plugin ever used were both accidental.
0.6.1 — the page describes the plugin again
Changed
-
The plugin page now describes what the plugin does. Its text had not moved
since 0.1.1 and named none of the five releases after it: no find-usages for a
response template, no endpoint list, noapi:lintrun from the IDE, no quick
fix that writes a missing action method, no comparison against validation
rules.Nothing in the code changed here. The description is read far more often than
it is written, and a stale one costs more than an unreleased feature: someone
deciding whether to install this was reading a list from which half of it was
missing.
0.6.0 — markup against validation
Added
-
A field the endpoint validates and the markup does not mention is now
reported, with a quick fix that writes the tag from the rule.This is a different failure from a dangling reference, and a harder one to
see: both sides are impeccable on their own. The rules are correct, the
docblock parses, the generated specification validates — and it describes a
different set of fields from the one the endpoint accepts.Measured before it was built. Of 52 endpoints across two real applications
with both readable rules and a docblock, nine disagreed: a public integration
API whose email delivery could not be called from its own documentation, a
bulk endpoint documentingitemswhile requiringids, six fields of a
dashboard layout described nowhere.The tag is written from what the rules actually say —
email→
string(email),nullable→?$,in:link,b64→[link,b64],
items.*.variables→$items[].variables— and no description is invented.
An empty description is honest; an invented one reads as considered.
Deliberately absent
-
Generating the markup wholesale from the code, which is what this release
was originally going to be. The measurement said otherwise: rules are readable
almost everywhere (one method in fifty-three is not), so generation saves
typing where typing was never the problem, while the disagreement between
rules and documentation is what nobody was looking at. -
The reverse direction — documented and not validated. Checked on the same
code:password_confirmationcomes from theconfirmedrule, and some fields
are validated dynamically against a column. Both are correct documentation,
and an inspection that argues with correct documentation is one people switch
off. -
@outputfrom the response. Half of the responses cannot be read at all,
their shapes vary more than rules do, and the cost of being wrong is the same:
a specification that is confidently mistaken is worse than one that is silent. -
Demanding a tag for
ids.*. An element of a scalar array has no form in
this markup — the generator drops such a tag without a word. Asking the author
to write a line that vanishes would be worse than asking nothing.
0.5.0 — writing the missing action method
Added
-
A quick fix that writes the controller method an action points at, on the
error that already reports the map leading nowhere. Alt+Enter on the action
key creates the method, with the name taken from the map rather than typed a
second time — a second, slightly different spelling produces exactly the 404
the fix exists to end.The docblock keeps what the neighbours agree on and invents nothing else.
@securityis copied, because authentication belongs to the controller rather
than to one action, and only when every sibling declares the same scheme;
where they differ, the choice is a decision and the line is left out.
@responseis never borrowed: a template names the body of that answer, and
copying one would document a response this method does not return — while
looking entirely deliberate.
0.4.0 — api:lint from the IDE
Added
-
api:lintruns from the IDE, in a Lint tab beside the endpoint list, or
from Tools → Run api:lint.Not for the convenience of not opening a terminal. The command carries
twenty-eight rules against the ten implemented here, and writing the other
eighteen in Kotlin would create a second truth that drifts from the first —
the very thing this plugin looks for in other people's code. So the fast
checks run as you type, and the whole set is asked of the application.Findings are clickable: their address is
version · controller.action, which
the route map turns into a method, so a double click opens the docblock the
finding is about.It needs
artisanand aphp. Where they are missing the reason is said in
words — availability is a file question, deliberately, so that a menu being
built does not depend on the index being ready.phpis looked for in the login shell's environment rather than the
launcher's. On macOS an IDE started from Finder inherits neither the shell's
PATH nor its version manager, so the first version of this told a developer
whose terminal runsphp artisanall day that there was no PHP on the
machine.