Skip to content

Commit

Permalink
[SecuritySolution][Timeline] Refactor timeline HTTP API (elastic#200633)
Browse files Browse the repository at this point in the history
## Summary

The timeline API endpoints are currently implemented from a mix of HTTP
and GraphQL practices. Since GraphQL has been removed for a long time
now, we should make sure the endpoints conform to HTTP best practices.
This will allow us to simplify the API- and client-logic. Further,
third-parties accessing these APIs will have an easier time integrating.

### Usage of HTTP status codes

Depending on the error, the API endpoints currently return a `200` with
`{ code: 404, message: '(...)' }` or an actual HTTP error response with
e.g. `403` and the message in the body. The practice of returning 200s
with embedded error codes comes from GraphQL, where error codes are
always embedded.

Example of a current HTTP response of a failed timeline request:

```
HTTP status: 200
HTTP body:
{
  "error_code": 409,
  "messsage": "there was a conflict"
}
```

Going forward, all endpoints should return proper error codes and embed
the error messages in the response body.
```
HTTP status: 409
HTTP body:
{
  "messsage": "there was a conflict"
}
```

### Removal of `{}` responses

Some timeline endpoints might return empty objects in case they were not
able to resolve/retrieve some SOs. The empty object implies a `404`
response. This creates complications on the client that now have to
provide extra logic for how to interpret empty objects.

Example of a current request of one of the endpoints that allows empty
responses.
```
HTTP status: 200
{}
```
The absence of an object, on some of the listed endpoints, indicates a
404 or the top-level or embedded saved object.

Going forward, the endpoints should not return empty objects and instead
return the proper HTTP error code (e.g. `404`) or a success code.

```
HTTP status: 404
```

### No more nested bodies

Another relic of the GraphQL time is the nesting of request bodies like
this:

```
HTTP status: 200
HTTP body:
{
  "data": {
    "persistTimeline": {
      (actual timeline object)
    }
  }
}
```

Combined with sometimes returning empty objects and potentially
returning a status code in the body, makes it overly complicated for
clients to reason about the response.

Going forward, the actual object(s) should be returned as a top-level
JSON object, omitting `data.persistX`.
```
HTTP status: 200
HTTP body:
{
  (actual timeline object)
}
```

### Checklist

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.

---------

Co-authored-by: kibanamachine <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
3 people authored and CAWilson94 committed Dec 12, 2024
1 parent 6029106 commit 4dd9f7f
Show file tree
Hide file tree
Showing 101 changed files with 1,130 additions and 3,521 deletions.
134 changes: 13 additions & 121 deletions oas_docs/output/kibana.serverless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31617,13 +31617,6 @@ paths:
required: true
responses:
'200':
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
type: object
properties:
data:
type: object
description: Indicates the note was successfully deleted.
summary: Delete a note
tags:
Expand Down Expand Up @@ -31685,9 +31678,7 @@ paths:
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
oneOf:
- $ref: '#/components/schemas/Security_Timeline_API_GetNotesResult'
- type: object
$ref: '#/components/schemas/Security_Timeline_API_GetNotesResult'
description: Indicates the requested notes were returned.
summary: Get notes
tags:
Expand Down Expand Up @@ -31731,17 +31722,7 @@ paths:
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
type: object
properties:
data:
type: object
properties:
persistNote:
$ref: '#/components/schemas/Security_Timeline_API_ResponseNote'
required:
- persistNote
required:
- data
$ref: '#/components/schemas/Security_Timeline_API_ResponseNote'
description: Indicates the note was successfully created.
summary: Add or update a note
tags:
Expand Down Expand Up @@ -32094,17 +32075,7 @@ paths:
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
type: object
properties:
data:
type: object
properties:
persistPinnedEventOnTimeline:
$ref: '#/components/schemas/Security_Timeline_API_PersistPinnedEventResponse'
required:
- persistPinnedEventOnTimeline
required:
- data
$ref: '#/components/schemas/Security_Timeline_API_PersistPinnedEventResponse'
description: Indicates the event was successfully pinned to the Timeline.
summary: Pin an event
tags:
Expand Down Expand Up @@ -33715,20 +33686,6 @@ paths:
required: true
responses:
'200':
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
type: object
properties:
data:
type: object
properties:
deleteTimeline:
type: boolean
required:
- deleteTimeline
required:
- data
description: Indicates the Timeline was successfully deleted.
summary: Delete Timelines or Timeline templates
tags:
Expand All @@ -33753,20 +33710,7 @@ paths:
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
oneOf:
- type: object
properties:
data:
type: object
properties:
getOneTimeline:
$ref: '#/components/schemas/Security_Timeline_API_TimelineResponse'
required:
- getOneTimeline
required:
- data
- additionalProperties: false
type: object
$ref: '#/components/schemas/Security_Timeline_API_TimelineResponse'
description: Indicates that the (template) Timeline was found and returned.
summary: Get Timeline or Timeline template details
tags:
Expand Down Expand Up @@ -34077,17 +34021,7 @@ paths:
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
type: object
properties:
data:
type: object
properties:
persistFavorite:
$ref: '#/components/schemas/Security_Timeline_API_FavoriteTimelineResponse'
required:
- persistFavorite
required:
- data
$ref: '#/components/schemas/Security_Timeline_API_FavoriteTimelineResponse'
description: Indicates the favorite status was successfully updated.
'403':
content:
Expand Down Expand Up @@ -34244,15 +34178,7 @@ paths:
content:
application/json; Elastic-Api-Version=2023-10-31:
schema:
oneOf:
- type: object
properties:
data:
$ref: '#/components/schemas/Security_Timeline_API_ResolvedTimeline'
required:
- data
- additionalProperties: false
type: object
$ref: '#/components/schemas/Security_Timeline_API_ResolvedTimeline'
description: The (template) Timeline has been found
'400':
description: The request is missing parameters
Expand Down Expand Up @@ -47290,16 +47216,10 @@ components:
Security_Timeline_API_FavoriteTimelineResponse:
type: object
properties:
code:
nullable: true
type: number
favorite:
items:
$ref: '#/components/schemas/Security_Timeline_API_FavoriteTimelineResult'
type: array
message:
nullable: true
type: string
savedObjectId:
type: string
templateTimelineId:
Expand Down Expand Up @@ -47468,28 +47388,15 @@ components:
- version
Security_Timeline_API_PersistPinnedEventResponse:
oneOf:
- allOf:
- $ref: '#/components/schemas/Security_Timeline_API_PinnedEvent'
- $ref: '#/components/schemas/Security_Timeline_API_PinnedEventBaseResponseBody'
- nullable: true
type: object
Security_Timeline_API_PersistTimelineResponse:
type: object
properties:
data:
type: object
- $ref: '#/components/schemas/Security_Timeline_API_PinnedEvent'
- type: object
properties:
persistTimeline:
type: object
properties:
timeline:
$ref: '#/components/schemas/Security_Timeline_API_TimelineResponse'
required:
- timeline
unpinned:
type: boolean
required:
- persistTimeline
required:
- data
- unpinned
Security_Timeline_API_PersistTimelineResponse:
$ref: '#/components/schemas/Security_Timeline_API_TimelineResponse'
Security_Timeline_API_PinnedEvent:
allOf:
- $ref: '#/components/schemas/Security_Timeline_API_BarePinnedEvent'
Expand All @@ -47502,15 +47409,6 @@ components:
required:
- pinnedEventId
- version
Security_Timeline_API_PinnedEventBaseResponseBody:
type: object
properties:
code:
type: number
message:
type: string
required:
- code
Security_Timeline_API_QueryMatchResult:
type: object
properties:
Expand Down Expand Up @@ -47551,15 +47449,9 @@ components:
Security_Timeline_API_ResponseNote:
type: object
properties:
code:
type: number
message:
type: string
note:
$ref: '#/components/schemas/Security_Timeline_API_Note'
required:
- code
- message
- note
Security_Timeline_API_RowRendererId:
enum:
Expand Down
Loading

0 comments on commit 4dd9f7f

Please sign in to comment.