Allow resending failed webook requests with the API
Problem to solve
GitLab provides the ability to resend webhook requests in the UI. Documentation here
A customer would like the ability to be able to resend any failed requests using the API so they can resend them programmatically when they have many failures (hundred or more).
Proposal
Add API endpoints that would allow users to resend failed project and group webhook requests. In the UI we call these webhook events.
We can do this by providing two endpoints each to project hooks and group hooks that would add extra value in general to our API besides just resending failed webhook events:
-
GET /{projects|groups}/:id/hooks/:hook_id/events
- this would expose the same data as when you edit a webhook in the UI and select Recent events.- It would allow filtering by the response status (to allow people to see only failures, for example)
- It would allow sorting by ascending or descending order
-
POST /{projects|groups}/:id/hooks/:hook_id/events/:hook_log_id/resend
- this would be the same functionality as in the controller when you resend any of theWebHookLog
records (resend the webhook event).
This would allow people to resend failed webhook requests in the follow way:
- See their webhook events in the API (parity with the UI).
- Filter those events to see the failures.
- Use the
id
of any event (including failures) to resend it (parity with the UI). - Control the rate at which those events are resent, and decide which order to send them in.
Implementation
Project hooks endpoints are defined in API::ProjectHooks
(lib/api/project_hooks.rb
).
Group hooks endpoints are defined in API::GroupHooks
(lib/api/group_hooks.rb
).
GET /{projects|groups}/:id/hooks/:hook_id/events
This will expose web_hook_logs
records for a webhook (WebHook#web_hook_logs
).
It must allow filtering by a statuses
argument.
statuses
would be:
- Any 3-digit integer that was an actual status codes, like
404
,200
, etc. - Or else a string. Either:
-
"success"
(which we would expand to all valid 2xx codes): -
"failure"
, (which we would expand to all valid 4xx-5xx codes)
-
- We could use
Rack::Utils::HTTP_STATUS_CODES.keys
to help us build sets of valid status codes for argument validation and for expanding strings to status codes. -
statuses
must allow multiple statuses passed in as comma-separated (like how people filter issues by labels).
To support this filtering we must first add a new database index to web_hook_logs.response_status
. Note, the web_hook_logs
table is very large on GitLab.com, so we may need close help/collaboration with Database reviewers.
We must allow sorting by a optional sort
argument. This would sort by WebHookLog#create_at
(there is an existing index in place).
sort
would be either "desc"
or "asc"
.
The default would be "desc"
.
POST /{projects|groups}/:id/hooks/:hook_id/events/:hook_log_id/resend
This will resend the WebHookLog
record.
We must create a new service for resending a webhook event called WebHooks::Events::ResendService
and refactor the existing controller logic to also use it.
Because the endpoint will execute a webhook in the request, which makes an external request to a server that might be slow to respond, the endpoint must queue a new worker WebHooks::Events::ResendWorker
which would call the new service.
We must add documentation of these endpoints to:
Workaround
Use the UI to resend requests, but this can be cumbersome when there are hundreds of failures.