Needs review
Project:
Overpass API
Version:
1.0.x-dev
Component:
Miscellaneous
Priority:
Normal
Category:
Task
Assigned:
Reporter:
Created:
25 Aug 2026 at 00:03 UTC
Updated:
15 Oct 2026 at 09:13 UTC
Jump to comment: Most recent
Although the overpass_api module is more general purpose, I think its functionality is already contained within the https://www.drupal.org/project/openstreetmap module. If you disagree, perhaps there's room for us to collaborate by making the openstreetmap module depend on the overpass_api module.
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
orkutmuratyilmaz@tbcs, thanks for raising this, and yes, let's collaborate:)
I agree the functionality overlaps, and I think the split you suggest is the right one.
openstreetmapowns the content model and the entities the data becomes.overpass_apiowns the query layer: building a query, running it, and getting the result back. Those are two jobs, and today each module does a bit of the other's.If
openstreetmapdepended onoverpass_apifor talking to an interpreter, you would lose the Overpass code you maintain today and this module would gain a real consumer. That seems worth more to both of us than either module growing towards the other.Two of my open issues touch this and I would rather decide them with you than around you.
#3614000 adds a config entity for saving and exporting queries. That sits in the query layer, so it stays here, but its shape should suit what Query Tools needs rather than only what my own UI needs. If you can say what your presets carry today, I will build against that.
#3614002 creates Feeds sources from the query builder to import OSM data. On the split above that is the content side, so it belongs with OpenStreetMap Module rather than with this one. There is a difference worth naming though: as I read it,
openstreetmapimports into OSM nodes, whereas what I had in mind targets any entity type, through Feeds. A term, a taxonomy of amenities, a custom entity for a municipal asset register: the OSM data is the source, and what it becomes is the site builder's decision rather than the module's.If that direction interests you, I would rather move it in the OpenStreetMap Module's issue queue than keep it in this one, and work on it there.
I should also ask murz, who owns
overpass_api, since a dependency in this direction is a commitment on this module's API and that is his call as much as mine.What would be the most useful next step from your side? I can look at what
overpass_apiwould need to expose for Query Tools to sit on top of it, if that helps.Comment #3
orkutmuratyilmazComment #4
tbcs commentedGreat, I'm glad to hear you're open to it. I did some research on both of our modules and came up with a plan. I'm working on a version 2.0 of
openstreetmapthat changes the PHP API without breaking existing data. I think the fundamental principle is: anything that manages the connection to Overpass lives inoverpass_api; anything about OpenStreetMap data (elements, tags, geometry, and what they become in Drupal) lives inopenstreetmap. Overpass is one way to retrieve OSM data; the OSM API, planet extracts and exported files are others, and the module boundary should mirror that.What that means for each piece:
overpass_api. Already here.overpass_api, per #3614000: Add overpass_api_preset submodule: Provide a Config Entity to save, reuse, and export Overpass queries.openstreetmapwill reference presets and store no query text of its own; it only stores what to do with a preset's results (destination bundle, schedule, orphan policy).overpass_api(overpass_api_ui). Already here.overpass_api, as anoverpass_api_feedssubmodule. This is the part of #3614002: Add overpass_api_feeds submodule: Allow creating Feeds sources directly from Query Builder (overpass_api_ui) to import OSM data that stays here.openstreetmap, as anopenstreetmap_feedssubmodule. It parses OSM data, which can also arrive through Feeds' own HTTP fetcher or an uploaded file, so it is not tied to Overpass. I'd suggest re-scoping #3614002: Add overpass_api_feeds submodule: Allow creating Feeds sources directly from Query Builder (overpass_api_ui) to import OSM data to the fetcher.openstreetmap. Consumed by its synchronizer and its Feeds parser.overpass_api. Response format handling is transport.A site that wants the full Feeds pipeline enables both submodules; a site that only wants OSM nodes never needs Feeds. I have a fuller list of what
openstreetmap2.0 would needoverpass_apito expose (a typed service interface, a result object that surfaces Overpassremarkerrors, batched fetch by id, streaming large results to a file, and the preset entity shape) and will post that as a separate issue. I'm working on an MR foroverpass_apisimultaneously and will post it to that issue when I post it.Comment #5
tbcs commentedActually, it might be better just to reuse (and rename) this issue. I'll post an MR here and a dev version of
openstreetmaplater today.Comment #7
orkutmuratyilmaz@tbcs, I'll update here in a week. Thanks for your commits and messages too:)
Comment #8
orkutmuratyilmaz@tbcs, I've just checked your bug fixes, thanks for the effort. I'm still going through the other parts of the MR.
Comment #9
orkutmuratyilmaz@tbcs, thanks again for this, and sorry it took a while. I've now been through all ten commits.
The bug fixes are clearly welcome: remark errors reported with HTTP 200,
ConnectExceptionnot being caught under Guzzle 7, the unused headers and injected client inrawQuery(), the bare;for an empty filter, the parenthesised{{bbox}}, andUtils::returnBytes()on-1. Thank you for tracking those down.Splitting the MR
Since this issue is now about the API surface, I'd like the MR to carry only that, and the rest to move to the issues it belongs to, so each part can be reviewed and land on its own. Concretely:
OverpassApi.php,OverpassApiInterface.php,OverpassApiHttpException.php,Utils.phpand their tests.overpass_api_presetsubmodule, as that issue describes; more on that there.SettingsFormandQueryBuilderForm, the lower install defaults, and "Fix the settings form fataling on Drupal 11" squashed into it. Released 1.0.x builds the form through autowiring and works on D11; the fatal comes from the new constructor in "Hardening", so the two belong together.tests/src/PHPCodeSniffer/Standard.php.Your authorship stays on all of it, of course.
Requests for the API part
OverpassApiInterface::query(): please documentobject[]only. The deprecatedreturnRawbranch can stay inOverpassApiuntil 2.0.0 (osm_localities still uses it), but I'd rather not put a deprecated flag into the interface contract.OverpassResultInterface::getElements(): please state that elements are returned as Overpass sent them, untransformed. Some consumers build on the raw elements directly (for example a way'snodestogether without geom), and I'd like that to be part of the contract rather than an implementation detail.getSlotAvailability(): could it return?intinstead ofbool|int?0for a free slot, the seconds to wait otherwise,NULLwhen the status report cannot be read. This is more than style: insendQuery(),if ($slotFreeTimeout !== TRUE) { $this->lock->acquire($this->lockName, $slotFreeTimeout); }passesFALSEto the lock,DatabaseLockBackend::acquire()clamps it to 1 ms, and an unreadable status is silently treated as a free slot. The same code is in 1.0.x today, so it isn't something you introduced, but the interface is the right moment to fix it: withNULLthe caller has to pick a fallback,lock_timefor instance.halaxa/json-machineis inrequire, so thehook_requirements()check for it can go. Keeping it inrequireis fine with me.Release
My plan is to ship the API part as 1.0.0-beta5, with release notes for the three behaviour changes (remark errors now throw
OverpassApiRuntimeException,OverpassApi::__construct()takes the lock backend,returnRawis deprecated), and then go to 1.0.0 on the new interface rather than open a 2.0.x branch.@murz, are you OK with breaking these in a beta? osm_localities is the consumer I know of: its main sync uses
returnRawand keeps working, butOsmSyncBatchcatches onlyOverpassApiHttpException, so a timed-out count query would now surface asOverpassApiRuntimeException. CatchingOverpassApiExceptionthere would cover both.Comment #10
orkutmuratyilmazFor reference, here is where each part of MR !9 would go. Commits are named by their short hash in the MR.
7d0bf522and9d4ad18bin full.2ed31651andac122b20, the API-side files:OverpassApi.php,OverpassApiInterface.php,OverpassApiHttpException.php,Utils.phpand their tests.OverpassApiInterface::query()documentsobject[]only;OverpassResultInterface::getElements()documents untransformed elements;getSlotAvailability()returns?int; thehook_requirements()check for json-machine goes.0e01cd65and7c353360, squashed.2ed31651: the preset route, entity link and list operation. Fromac122b20: the duplicate form fix.overpass_api_presetsubmodule;overpass_api.query_builderstays in the main module.config/install, and a kernel test.cccf14c8.ac122b20: the fetcher tests.openstreetmap_feeds. Depends onoverpass_api_preset.2ed31651:SettingsForm,QueryBuilderFormand the install defaults (60 s timeout, 3 attempts).d425b45asquashed into it.703f91ffand62c06d35.2ed31651: the removal oftests/src/PHPCodeSniffer/Standard.php.polymode, an area passed in at run time, or both.Landing order: this issue first. Then presets, form hardening and packaging, in any order. The Feeds fetcher after presets, since it depends on them.
Comment #11
tbcs commentedNew issues from #10:
MR !9 now carries only the API surface:
7d0bf52and9d4ad18unchanged, the API-side files from the hardening and duplicate-form commits, and the four requested changes:OverpassApiInterface::query()documentsobject[]only. ThereturnRawbranch is documented onOverpassApi.OverpassResultInterface::getElements()anditerateElements()document untransformed elements.getSlotAvailability()returns?int.sendQuery()falls back onlock_timefor NULL and leaves the lock alone for a free slot; both are covered by tests.hook_requirements()check for json-machine is gone.The previous head is tagged
previous/3618910-expose-surface-for/2026-10-12.Comment #12
orkutmuratyilmaz@tbcs, thank you for the quick re-cut and for opening #3630442: Inject services into SettingsForm and QueryBuilderForm, and lower the retry defaults, #3630443: Move UI dependencies to suggest, default to the https endpoint, and add CI and #3630444: Polygon areas for presets. All four requests are in, and the
lock_timefallback for an unreadable status report is exactly what I hoped for.I checked the remark detection against live Overpass answers: "runtime error: Query run out of memory using about 2048 MB of RAM." and "runtime error: Query ran out of memory in "query" at line 1. It would need at least 32 MB of RAM to continue." both come back as HTTP 200 with no elements, and both are caught by the pattern. An area that does not exist returns an empty result with no remark, which correctly is not an error.
I pushed one commit on top, because it is about the contract this MR establishes: "Wrap every transport failure in OverpassApiException". The interface says the service throws
OverpassApiExceptionon an unrecoverable transport error, but three paths let a raw Guzzle exception through:sendQuery()rethrew the Guzzle exception as is, so a 400 (an Overpass QL parse error) arrived asClientException;ConnectExceptionstill failing on the last attempt was rethrown raw;getStatus()had no catch at all, and withuse_slots_timeoutsit runs insidesendQuery().They now go through a small
wrapTransportException():OverpassApiHttpExceptionwhen there is a response, otherwiseOverpassApiExceptionwith the Guzzle exception as previous.testRawQueryDoesNotRetryBadRequest()asserts the type now, and two new tests cover an exhausted connect failure andgetStatus(). All 54 unit tests pass with PHPUnit 11, and the new ones fail against the previous head. Please have a look and tell me if you'd rather shape it differently.One housekeeping point: the MR title and description still describe the original ten commits (presets, Feeds fetcher, packaging,
overpass_api.preset.*config dependencies). Could you update them to the API surface only? I'll also tidy the stray capitals in two of the commit messages ("paSs", "boDy", "untransformeD", "lonGer") in the squash message when merging.If nothing else comes up, I'll merge this in a few days and release it as 1.0.0-beta5, with release notes for the behaviour changes: remark errors are now thrown as
OverpassApiRuntimeException, transport errors always arrive asOverpassApiException,OverpassApi::__construct()takes the lock backend, andreturnRawis deprecated. osm_localities keeps working; the one visible change there is that a timed-out count query now surfaces asOverpassApiRuntimeException.