-
Notifications
You must be signed in to change notification settings - Fork 86
Introduce /api/workitems/:ID/relationships/links #525
Conversation
Current coverage is 66.37% (diff: 26.66%)@@ master #525 diff @@
==========================================
Files 62 63 +1
Lines 3286 3316 +30
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 2193 2201 +8
- Misses 857 878 +21
- Partials 236 237 +1
|
Are you considering POST to this relation as well for Adding links to the WorkItem? |
Should we consider this PR the fix for #475 ? |
I am considering POST but this PR is supposed to stay small and make its way into master quicker than the last one ;)
It is a part #475 but the workitems endpoint needs to include the relationships as well. That I want to do in another PR as well. |
Sure. hehe. Just didn't see any Task|Issue related to it, was just wondering. |
b55718a
to
285f530
Compare
Current coverage is 68.40% (diff: 69.29%)@@ master #525 diff @@
==========================================
Files 70 71 +1
Lines 3644 3754 +110
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 2492 2568 +76
- Misses 889 915 +26
- Partials 263 271 +8
|
2799659
to
70fb0d0
Compare
4d25300
to
3895561
Compare
[test] |
1 similar comment
[test] |
803911b
to
e15cc61
Compare
e15cc61
to
d71c3e0
Compare
This change will introduce the endpoint `/api/workitems/:ID/relationships/links` for work item links that lives under the work item endpoint and automatically filters work item links associated with the work item on the backend. You can also use this endpoint as you would use the `/api/workitemlinks/` endpoint. Also, this change will introduce the `included` top-level JSONAPI element for responses of `/api/workitemlinks/` that return work item links or arrays of work item links. Currently this `included` element will contain only objects of type work item link type. Currently the UI has to do the filtering of links on a particular work item. This should be no longer needed. == Checks In the WorkItemRelationshipsLinksController we perform the following checks for the listed actions. === Create action * We check that the current work item (:id) does exist. * Check that the source ID of the link is the same as the current work item ID (:id). * If no source is specified we pre-fill the source field of the payload with the current work item ID from the URL. This is for convenience. === Delete action * We check that the work item (:linkid) does exist. * Check that the source ID of the link to be deleted is the same as the current work item ID (:id). === List action * No checks are done === Show action * We check that the work item (:linkid) does exist. * Check that the source ID or target ID of the link to be shown is the same as the current work item ID (:id). === Update action * We check that the work item (:linkid) does exist. * Check that the source ID of the link to be updated is the same as the current work item ID (:id). * Check that the source ID of the update payload is the same as the current work item ID (:id). See also fabric8-services#307
d71c3e0
to
64c90c7
Compare
I would like to see include of source/target workitems (where source/target != this) as well, to avoid the UI having to do n backend calls per link to display the basic information like Title, State, ID. Doesn't have to be part of this PR tho. Just in general :) |
@aslakknutsen thanks for approving.
Yes, that's what I intended with this issue: "Include related resources by default in all actions and endpoints that deal with work item links." #533 |
}) | ||
}) | ||
|
||
// listWorkItemLinks defines the list action for endpoints that return an array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, this refactoring makes it impossible to see if you have made any changes to this code. Generally, I would do such mechanical but sweeping changes in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about that. Will try to not do it again.
func ParseWorkItemIDToUint64(wiIDStr string) (uint64, error) { | ||
wiID, err := strconv.ParseUint(wiIDStr, 10, 64) | ||
if err != nil { | ||
return 0, errors.NewBadParameterError("work item ID", wiIDStr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think "BadParameter" is correct. In the API, the ID is just a string, so if it is "abcd", that's not a wrong request, just an id that we happen to know we won't find in the db.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Fixed in local branch.
@@ -535,7 +535,7 @@ var _ = a.Resource("work-item-link-type", func() { | |||
a.Routing( | |||
a.GET("/:id"), | |||
) | |||
a.Description("Retrieve work item link type (as JSONAPI) for the given ID.") | |||
a.Description("Retrieve work item link type (as JSONAPI) for the given link ID.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Link id or link type id?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tsmaeder good catch. It is supposed to be "link type id". Fixed in local branch.
// CheckWorkItemExists returns nil if no work item ID string is given or if work | ||
// item ID string could be converted into a number and looked up in the | ||
// database; otherwise it returns an error. | ||
func CheckWorkItemExists(db *gorm.DB, wiIDStr string) (*WorkItem, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you add this as a method in the gorm work item repo, you don't need to pass in the db.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found I can use WorkItemRepository.LoadFromDB instead. It does the same thing.
// item ID string could be converted into a number and looked up in the | ||
// database; otherwise it returns an error. | ||
func CheckWorkItemExists(db *gorm.DB, wiIDStr string) (*WorkItem, error) { | ||
if db == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a programming error to pass in a nil db here. I don't think we should check invariants of the code, just let it crash.
if db.Error != nil { | ||
return nil, db.Error | ||
db := r.db | ||
if wiIDStr == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like dispatching on a nil parameter. These are really two different methods. We can reuse the common parts of the code in different ways.
At the API level, it's fine to introduce parameters as optional first in order to facilitate migration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I agree. Will outsource into separate function.
var _ = a.Resource("work-item-relationships-links", func() { | ||
a.BasePath("/relationships/links") | ||
a.Parent("workitem") | ||
a.Action("show", showWorkItemLink) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The more I think about it, the less I think treating link object like a simple relationship makes sense. When I create a link, it is necessarily always related to two work items (and vice versa). A link is not a relationship between two work items. It is a resource object in it's own right. We cannot remove or add relationships here without deleting or creating new resource objects. That is not what jsonapi relationships are.
Therefore, I don't think having create, update and delete here makes sense, only list (and perhaps show).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Thank you for sharing your thoughts. @aslakknutsen I'd like to remove the CUD operations from the /api/workitems/:id/relationships/links/:linkid
endpoint. Such operations have to made on the actual resource endpoint /api/work-item-links/:linkid
.
According to @tsmaeder 's comments on fabric8-services#525 (after it was being merged), this change includes some cleanups. * Return NotFoundError instead of BadParameterError when parsing a WI ID * Split WorkItemLinkRepository.List into List and ListByWorkItemID * Removed this generic List method from the WorkItemLinkRepository List(ctx context.Context, wiIDStr *string) (*app.WorkItemLinkArray, error) and replaced it with these less generic methods: List(ctx context.Context) (*app.WorkItemLinkArray, error) ListByWorkItemID(ctx context.Context, wiIDStr string) (*app.WorkItemLinkArray, error) * Let crash if db is nil * No need for workitem.CheckWorkItemExists() * There's a WorkItemRepository.LoadFromDB that basically does the same thing. * Remove obsolete comment
According to @tsmaeder 's comments on fabric8-services#525 (after it was being merged), this change includes some cleanups. * Return NotFoundError instead of BadParameterError when parsing a WI ID * Split WorkItemLinkRepository.List into List and ListByWorkItemID * Removed this generic List method from the WorkItemLinkRepository List(ctx context.Context, wiIDStr *string) (*app.WorkItemLinkArray, error) and replaced it with these less generic methods: List(ctx context.Context) (*app.WorkItemLinkArray, error) ListByWorkItemID(ctx context.Context, wiIDStr string) (*app.WorkItemLinkArray, error) * Let crash if db is nil * No need for workitem.CheckWorkItemExists() * There's a WorkItemRepository.LoadFromDB that basically does the same thing. * Remove obsolete comment
According to @tsmaeder 's comments on #525 (after it was being merged), this change includes some cleanups. * Return NotFoundError instead of BadParameterError when parsing a WI ID * Split WorkItemLinkRepository.List into List and ListByWorkItemID * Removed this generic List method from the WorkItemLinkRepository List(ctx context.Context, wiIDStr *string) (*app.WorkItemLinkArray, error) and replaced it with these less generic methods: List(ctx context.Context) (*app.WorkItemLinkArray, error) ListByWorkItemID(ctx context.Context, wiIDStr string) (*app.WorkItemLinkArray, error) * Let crash if db is nil * No need for workitem.CheckWorkItemExists() * There's a WorkItemRepository.LoadFromDB that basically does the same thing. * Remove obsolete comment
This change will introduce the endpoint
/api/workitems/:ID/relationships/links
for work item links that lives under the work item endpoint and automatically filters work item links associated with the work item on the backend. You can also use this endpoint as you would use the/api/workitemlinks/
endpoint.Also, this change will introduce the
included
top-level JSONAPI element for responses of/api/workitemlinks/
that return work item links or arrays of work item links. Currently thisincluded
element will contain only objects of type work item link type.Currently the UI has to do the filtering of links on a particular work item. This should be no longer needed.
Checks
In the WorkItemRelationshipsLinksController we perform the following
checks for the listed actions.
Create action
item ID (:id).
with the current work item ID from the URL. This is for convenience.
Delete action
current work item ID (:id).
List action
Show action
same as the current work item ID (:id).
Update action
current work item ID (:id).
current work item ID (:id).
See also #307