Skip to content

Commit 989b862

Browse files
authored
Merge pull request #38 from Research-Institute/meta-objects
Meta objects
2 parents 605e039 + 456d65c commit 989b862

File tree

15 files changed

+247
-22
lines changed

15 files changed

+247
-22
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ JsonApiDotnetCore provides a framework for building [json:api](http://jsonapi.or
2424
- [Pagination](#pagination)
2525
- [Filtering](#filtering)
2626
- [Sorting](#sorting)
27+
- [Meta](#meta)
2728
- [Tests](#tests)
2829

2930
## Installation
@@ -240,6 +241,18 @@ when setting up the services:
240241
opt => opt.DefaultPageSize = 10);
241242
```
242243

244+
**Total Record Count**
245+
246+
The total number of records can be added to the document meta by setting it in the options:
247+
248+
```
249+
services.AddJsonApi<AppDbContext>(opt =>
250+
{
251+
opt.DefaultPageSize = 5;
252+
opt.IncludeTotalRecordCount = true;
253+
});
254+
```
255+
243256
### Filtering
244257

245258
You can filter resources by attributes using the `filter` query parameter.
@@ -270,6 +283,25 @@ Resources can be sorted by an attribute:
270283
?sort=-attribute // descending
271284
```
272285

286+
### Meta
287+
288+
Resource meta can be defined by implementing `IHasMeta` on the model class:
289+
290+
```
291+
public class Person : Identifiable<int>, IHasMeta
292+
{
293+
// ...
294+
295+
public Dictionary<string, object> GetMeta(IJsonApiContext context)
296+
{
297+
return new Dictionary<string, object> {
298+
{ "copyright", "Copyright 2015 Example Corp." },
299+
{ "authors", new string[] { "Jared Nance" } }
300+
};
301+
}
302+
}
303+
```
304+
273305
## Tests
274306

275307
I am using DotNetCoreDocs to generate sample requests and documentation.

src/JsonApiDotNetCore/Builders/DocumentBuilder.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using JsonApiDotNetCore.Extensions;
45
using JsonApiDotNetCore.Internal;
56
using JsonApiDotNetCore.Models;
@@ -24,7 +25,8 @@ public Document Build(IIdentifiable entity)
2425

2526
var document = new Document
2627
{
27-
Data = _getData(contextEntity, entity)
28+
Data = _getData(contextEntity, entity),
29+
Meta = _getMeta(entity)
2830
};
2931

3032
document.Included = _appendIncludedObject(document.Included, contextEntity, entity);
@@ -42,7 +44,8 @@ public Documents Build(IEnumerable<IIdentifiable> entities)
4244

4345
var documents = new Documents
4446
{
45-
Data = new List<DocumentData>()
47+
Data = new List<DocumentData>(),
48+
Meta = _getMeta(entities.FirstOrDefault())
4649
};
4750

4851
foreach (var entity in entities)
@@ -54,6 +57,23 @@ public Documents Build(IEnumerable<IIdentifiable> entities)
5457
return documents;
5558
}
5659

60+
private Dictionary<string, object> _getMeta(IIdentifiable entity)
61+
{
62+
if (entity == null) return null;
63+
64+
var meta = new Dictionary<string, object>();
65+
var metaEntity = entity as IHasMeta;
66+
67+
if(metaEntity != null)
68+
meta = metaEntity.GetMeta(_jsonApiContext);
69+
70+
if(_jsonApiContext.Options.IncludeTotalRecordCount)
71+
meta["total-records"] = _jsonApiContext.TotalRecords;
72+
73+
if(meta.Count > 0) return meta;
74+
return null;
75+
}
76+
5777
private List<DocumentData> _appendIncludedObject(List<DocumentData> includedObject, ContextEntity contextEntity, IIdentifiable entity)
5878
{
5979
var includedEntities = _getIncludedEntities(contextEntity, entity);

src/JsonApiDotNetCore/Configuration/JsonApiOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ public class JsonApiOptions
44
{
55
public string Namespace { get; set; }
66
public int DefaultPageSize { get; set; }
7+
public bool IncludeTotalRecordCount { get; set; }
78
}
89
}

src/JsonApiDotNetCore/Controllers/JsonApiController.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ public virtual async Task<IActionResult> GetAsync()
6464
if (_jsonApiContext.QuerySet != null && _jsonApiContext.QuerySet.IncludedRelationships != null && _jsonApiContext.QuerySet.IncludedRelationships.Count > 0)
6565
entities = IncludeRelationships(entities, _jsonApiContext.QuerySet.IncludedRelationships);
6666

67+
if (_jsonApiContext.Options.IncludeTotalRecordCount)
68+
_jsonApiContext.TotalRecords = await entities.CountAsync();
69+
6770
// pagination should be done last since it will execute the query
6871
var pagedEntities = await ApplyPageQueryAsync(entities);
6972

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
using System.Collections.Generic;
21
using Newtonsoft.Json;
32

43
namespace JsonApiDotNetCore.Models
54
{
6-
public class Document
5+
public class Document : DocumentBase
76
{
87
[JsonProperty("data")]
98
public DocumentData Data { get; set; }
10-
11-
[JsonProperty("included")]
12-
public List<DocumentData> Included { get; set; }
139
}
1410
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace JsonApiDotNetCore.Models
5+
{
6+
public class DocumentBase
7+
{
8+
[JsonProperty("included")]
9+
public List<DocumentData> Included { get; set; }
10+
public Dictionary<string, object> Meta { get; set; }
11+
}
12+
}

src/JsonApiDotNetCore/Models/Documents.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@
33

44
namespace JsonApiDotNetCore.Models
55
{
6-
public class Documents
6+
public class Documents : DocumentBase
77
{
88
[JsonProperty("data")]
99
public List<DocumentData> Data { get; set; }
10-
11-
[JsonProperty("included")]
12-
public List<DocumentData> Included { get; set; }
1310
}
1411
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Collections.Generic;
2+
using JsonApiDotNetCore.Services;
3+
4+
namespace JsonApiDotNetCore.Models
5+
{
6+
public interface IHasMeta
7+
{
8+
Dictionary<string, object> GetMeta(IJsonApiContext context);
9+
}
10+
}

src/JsonApiDotNetCore/Services/IJsonApiContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ public interface IJsonApiContext
1515
QuerySet QuerySet { get; set; }
1616
bool IsRelationshipData { get; set; }
1717
List<string> IncludedRelationships { get; set; }
18+
int TotalRecords { get; set; }
1819
}
1920
}

src/JsonApiDotNetCore/Services/JsonApiContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ public JsonApiContext(
2020
_httpContextAccessor = httpContextAccessor;
2121
Options = options;
2222
}
23+
2324
public JsonApiOptions Options { get; set; }
2425
public IContextGraph ContextGraph { get; set; }
2526
public ContextEntity RequestEntity { get; set; }
2627
public string BasePath { get; set; }
2728
public QuerySet QuerySet { get; set; }
2829
public bool IsRelationshipData { get; set; }
2930
public List<string> IncludedRelationships { get; set; }
31+
public int TotalRecords { get; set; }
3032

3133
public IJsonApiContext ApplyContext<T>()
3234
{

0 commit comments

Comments
 (0)