-
-
Notifications
You must be signed in to change notification settings - Fork 5
task: improve docs for custom persistence options #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ dotnet add package JsonApiDotNetCore.MongoDb | |
### Models | ||
|
||
```cs | ||
// MongoDbIdentifiable is just a utility base class, could use IIdentifiable<TId> instead | ||
public sealed class Book : MongoDbIdentifiable | ||
{ | ||
[Attr] | ||
|
@@ -63,14 +64,16 @@ public class Startup | |
} | ||
} | ||
``` | ||
|
||
Note: If your API project uses only MongoDB (not in combination with EF Core), then instead of | ||
registering all MongoDB resources and repositories individually, you can use: | ||
|
||
```cs | ||
public class Startup | ||
{ | ||
public IServiceProvider ConfigureServices(IServiceCollection services) | ||
{ | ||
// ... | ||
// ... | ||
|
||
services.AddJsonApi(facade => facade.AddCurrentAssembly()); | ||
services.AddJsonApiMongoDb(); | ||
|
@@ -85,6 +88,60 @@ public class Startup | |
} | ||
``` | ||
|
||
### Customise MongoDB persistence options and _id generation | ||
|
||
In addition to `MongoDbIdentifiable` your resource classes are free to use any of the MongoDB driver persistence options or inherit from their own base class. | ||
|
||
For example, you could change the example above so that the `Book` resource has string IDs rather than object ids in the DB, but still have them generated server side: | ||
|
||
```cs | ||
public class Book : IIdentifiable<string> | ||
{ | ||
// If Id=null generate a random string ID using the MongoDB driver | ||
[BsonId(IdGenerator = typeof(StringObjectIdGenerator))] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The default of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good to know, then I think we should leave that the default. |
||
[Attr] | ||
public virtual string Id { get; set; } | ||
|
||
// override the attribute name in the db | ||
[BsonElement("bookName")] | ||
[Attr] | ||
public string Name { get; set; } | ||
|
||
// all json:api resources need this | ||
[BsonIgnore] | ||
public string StringId { get => Id; set => Id = value; } | ||
} | ||
``` | ||
|
||
Resources just need to inherit from the base `IIdentifiable<string>` interface from JsonApiDotNetCore (or the provided default `MongoDbIdentifiable`) and then just use any of usual [MongoDB Driver mapping code](https://mongodb.github.io/mongo-csharp-driver/2.12/reference/bson/mapping/). | ||
|
||
You could also achieve the exact same result using MongoDB `BsonClassMap` [rather than attributes](https://mongodb.github.io/mongo-csharp-driver/2.11/reference/bson/mapping/) so your `Book` does not need any MongoDB specific code like below. | ||
|
||
```cs | ||
// in startup | ||
BsonClassMap.RegisterClassMap<Book>(cm => | ||
{ | ||
cm.AutoMap(); | ||
cm.MapIdProperty(x => x.Id).SetIdGenerator(StringObjectIdGenerator.Instance); | ||
cm.UnmapMember(x=>x.StringId); | ||
}); | ||
``` | ||
|
||
Using `StringObjectIdGenerator` above could then be combined with `AllowClientGeneratedIds` JsonApi setting in `Startup.ConfigureServices` so that IDs can be generated on the client, and will be auto-assigned server side if not provided providing a flexible string based id for the `Book` resource: | ||
|
||
```cs | ||
services.AddJsonApi(options => { | ||
// Allow us to POST books with already assigned IDs! | ||
options.AllowClientGeneratedIds = true; | ||
}, resources: builder => | ||
{ | ||
builder.Add<Book, string>(); | ||
}); | ||
services.AddJsonApiMongoDb(); | ||
|
||
services.AddResourceRepository<MongoDbRepository<Book, string>>(); | ||
``` | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is basic JsonApiDotNetCore functionality, which is already documented at https://www.jsonapi.net/usage/options.html#client-generated-ids. I don't see why it needs to be mentioned here, or am I missing something that makes this work differently for MongoDB that requires explanation? Note we have MongoDB-tests for this and all seem to work fine without any special handling. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The combination of mongoDB features (string ids generated server side) and json api features (optional client side id generation) working in tandem was hard to discover for me and took me a few passes to figure out which was why I was offering some docs up to save others the same hassle but accept what you say. I think it is MongoDB specific because the library is defaulted to the (performant) binary object id. If you are trying to do client side id generation with AllowClientGeneratedIds then users (me!) may assume they can pass any string id since that is how the API appears. However, in reality the API requires you to pass a 12 byte unique generated object id, and throws an non-obvious exception if you just pass something like Using mongoDB There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. But then we should have tests backing that scenario, if we're going to advise on doing that. Can you add some? They would demonstrate using the fluent mapping overrides too, which is nice. |
||
## Development | ||
|
||
Restore all NuGet packages with: | ||
|
Uh oh!
There was an error while loading. Please reload this page.