Skip to content

Commit c633c71

Browse files
authored
Merge pull request #458 from milosloub/feat/#406
Feat(#406): Allow filter[id] and filter[related.id]
2 parents bd162d0 + 7268b66 commit c633c71

File tree

4 files changed

+68
-4
lines changed

4 files changed

+68
-4
lines changed

Diff for: src/JsonApiDotNetCore/Builders/ContextGraphBuilder.cs

+12
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ protected virtual List<AttrAttribute> GetAttributes(Type entityType)
139139

140140
foreach (var prop in properties)
141141
{
142+
if (prop.Name == nameof(Identifiable.Id))
143+
{
144+
var idAttr = new AttrAttribute()
145+
{
146+
PublicAttributeName = JsonApiOptions.ResourceNameFormatter.FormatPropertyName(prop),
147+
PropertyInfo = prop,
148+
InternalAttributeName = prop.Name
149+
};
150+
attributes.Add(idAttr);
151+
continue;
152+
}
153+
142154
var attribute = (AttrAttribute)prop.GetCustomAttribute(typeof(AttrAttribute));
143155
if (attribute == null)
144156
continue;

Diff for: src/JsonApiDotNetCore/Builders/DocumentBuilder.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ public ResourceObject GetData(ContextEntity contextEntity, IIdentifiable entity,
141141
private bool ShouldIncludeAttribute(AttrAttribute attr, object attributeValue)
142142
{
143143
return OmitNullValuedAttribute(attr, attributeValue) == false
144+
&& attr.InternalAttributeName != nameof(Identifiable.Id)
144145
&& ((_jsonApiContext.QuerySet == null
145146
|| _jsonApiContext.QuerySet.Fields.Count == 0)
146147
|| _jsonApiContext.QuerySet.Fields.Contains(attr.InternalAttributeName));
@@ -280,10 +281,13 @@ private ResourceObject GetIncludedEntity(IIdentifiable entity)
280281

281282
data.Attributes = new Dictionary<string, object>();
282283

283-
contextEntity.Attributes.ForEach(attr =>
284+
foreach(var attr in contextEntity.Attributes)
284285
{
286+
if (attr.InternalAttributeName == nameof(Identifiable.Id))
287+
continue;
288+
285289
data.Attributes.Add(attr.PublicAttributeName, attr.GetValue(entity));
286-
});
290+
}
287291

288292
return data;
289293
}

Diff for: test/JsonApiDotNetCoreExampleTests/Acceptance/TodoItemsControllerTests.cs

+48
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,54 @@ public async Task Can_Get_TodoItems()
6969
Assert.True(deserializedBody.Count <= expectedEntitiesPerPage);
7070
}
7171

72+
[Fact]
73+
public async Task Can_Filter_By_Resource_Id()
74+
{
75+
// Arrange
76+
var todoItem = _todoItemFaker.Generate();
77+
_context.TodoItems.Add(todoItem);
78+
_context.SaveChanges();
79+
80+
var httpMethod = new HttpMethod("GET");
81+
var route = $"/api/v1/todo-items?filter[id]={todoItem.Id}";
82+
var request = new HttpRequestMessage(httpMethod, route);
83+
84+
// Act
85+
var response = await _fixture.Client.SendAsync(request);
86+
var body = await response.Content.ReadAsStringAsync();
87+
var deserializedBody = _fixture.GetService<IJsonApiDeSerializer>().DeserializeList<TodoItem>(body);
88+
89+
// Assert
90+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
91+
Assert.NotEmpty(deserializedBody);
92+
Assert.Contains(deserializedBody, (i) => i.Id == todoItem.Id);
93+
}
94+
95+
[Fact]
96+
public async Task Can_Filter_By_Relationship_Id()
97+
{
98+
// Arrange
99+
var person = new Person();
100+
var todoItem = _todoItemFaker.Generate();
101+
todoItem.Owner = person;
102+
_context.TodoItems.Add(todoItem);
103+
_context.SaveChanges();
104+
105+
var httpMethod = new HttpMethod("GET");
106+
var route = $"/api/v1/todo-items?filter[owner.id]={person.Id}";
107+
var request = new HttpRequestMessage(httpMethod, route);
108+
109+
// Act
110+
var response = await _fixture.Client.SendAsync(request);
111+
var body = await response.Content.ReadAsStringAsync();
112+
var deserializedBody = _fixture.GetService<IJsonApiDeSerializer>().DeserializeList<TodoItem>(body);
113+
114+
// Assert
115+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
116+
Assert.NotEmpty(deserializedBody);
117+
Assert.Contains(deserializedBody, (i) => i.OwnerId == person.Id);
118+
}
119+
72120
[Fact]
73121
public async Task Can_Filter_TodoItems()
74122
{

Diff for: test/UnitTests/Builders/ContextGraphBuilder_Tests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public void Attrs_Without_Names_Specified_Will_Use_Default_Formatter()
9494

9595
// assert
9696
var resource = graph.GetContextEntity(typeof(TestResource));
97-
Assert.Equal("compound-attribute", resource.Attributes.Single().PublicAttributeName);
97+
Assert.Contains(resource.Attributes, (i) => i.PublicAttributeName == "compound-attribute");
9898
}
9999

100100
[Fact]
@@ -110,7 +110,7 @@ public void Attrs_Without_Names_Specified_Will_Use_Configured_Formatter()
110110

111111
// assert
112112
var resource = graph.GetContextEntity(typeof(TestResource));
113-
Assert.Equal("compoundAttribute", resource.Attributes.Single().PublicAttributeName);
113+
Assert.Contains(resource.Attributes, (i) => i.PublicAttributeName == "compoundAttribute");
114114
}
115115

116116
[Fact]

0 commit comments

Comments
 (0)