Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,27 @@ public <R extends ElideEntity> ElideNavigatorSelector<R> navigateRelationship(@N
return new ElideNavigator<>(dtoClass, this);
}

@Override
public <R extends ElideEntity> ElideNavigatorOnRelationshipLink<R> relationshipLink(@NotNull Class<R> entityClass,
@NotNull String name) {
if (!includes.isEmpty()) {
throw new IllegalStateException("Cannot navigate to a relationship link with includes on parent");
}
log.trace("relationship link added: {}", name);
String route = build() + "/relationships/" + name;
return new ElideNavigatorOnRelationshipLink<>() {
@Override
public String build() {
return route;
}

@Override
public Class<R> getDtoClass() {
return entityClass;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
};
}

/**
* Add a sorting rule to the navigator
* Important: You need to give the full qualified route, there is NO referencing of parent relationships.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,17 @@ public interface ElideNavigatorOnId<T extends ElideEntity> extends ElideEndpoint

<R extends ElideEntity> ElideNavigatorSelector<R> navigateRelationship(Class<R> entityClass, String name);

/**
* Points the navigator at the JSON:API relationship endpoint
* ({@code /data/{type}/{id}/relationships/{name}}), used to read or modify the relationship linkage itself
* (e.g. PATCH/POST/DELETE to add, replace or remove members). This differs from
* {@link #navigateRelationship(Class, String)}, which addresses the related resource(s).
*
* <p>This is a terminal operation: the returned navigator only allows {@link
* ElideNavigatorOnRelationshipLink#build()}. Includes are not allowed on the parent.
*
* @param entityClass the type of the related resource(s) the linkage points at
*/
<R extends ElideEntity> ElideNavigatorOnRelationshipLink<R> relationshipLink(Class<R> entityClass, String name);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.faforever.commons.api.elide;

/**
* Terminal navigator pointing at a JSON:API relationship endpoint
* ({@code /data/{type}/{id}/relationships/{name}}). It only exposes {@link #build()} and the related entity
* type, because a relationship link addresses the linkage itself (read or modify via PATCH/POST/DELETE) and
* cannot be navigated further. {@code T} is the type of the related resource(s) the linkage points at.
*/
public interface ElideNavigatorOnRelationshipLink<T extends ElideEntity> {
String build();

Class<T> getDtoClass();
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,33 @@ void testNavigateFromIdToId() {
.build(), is("/data/mapPool/5/mapVersion/1234?include=author"));
}

@Test
void testRelationshipLink() {
ElideNavigatorOnRelationshipLink<MapVersion> navigator = ElideNavigator.of(MapPool.class)
.id("5")
.relationshipLink(MapVersion.class, "mapVersion");
assertThat(navigator.build(), is("/data/mapPool/5/relationships/mapVersion"));
assertThat(navigator.getDtoClass(), is(MapVersion.class));
}

@Test
void testRelationshipLinkAfterNavigateRelationship() {
assertThat(ElideNavigator.of(MapPool.class)
.id("5")
.navigateRelationship(MapVersion.class, "mapVersion")
.id("1234")
.relationshipLink(MapVersion.class, "map")
.build(), is("/data/mapPool/5/mapVersion/1234/relationships/map"));
}

@Test
void testCannotRelationshipLinkAfterIncludes() {
assertThrows(IllegalStateException.class, () -> ElideNavigator.of(MapPool.class)
.id("5")
.addInclude("mapVersion")
.relationshipLink(MapVersion.class, "mapVersion"));
}

@Test
void testGetListPages() {
assertThat(ElideNavigator.of(MapPoolAssignment.class)
Expand Down
Loading