9

I'm currently struggling with something that should be trivial, and maybe it is, but I can't find a decent solution.

My problem originates with RavenDB default ID structure. Let's say we use the HiLo algorithm to create a person, we'll get our first document:

people/A-1

And the related collection "People" has now one member.

My problem is really simple: designing a normal RESTful method to get a single person:

GET people/:id

And calling it with the sample document ID, my call will become:

GET people/people/A-1

Which will obviously not work, since the slash character is the route separator character, but with RavenDB it's also part of the entity ID.

I've tried using a different separator (changing the conventions on my client code), so to get an ID like people#A-1 but this is not recognized by RavenDB Studio: if I try to "link" two documents together by their ID, only the standard format gets recognized. Also I couldn't find a way to set the convention on the database at server level, but only at client level.

This solution also feels like a dirty workaround, and I'm looking for the proper way of doing things.

I know I can use arbitrary IDs, like email addresses without any prefix, but this isn't feasible for all kinds of entities I'm going to store, natural key isn't an option in every scenario.

So I'm asking to anyone who is more experienced than me in using RavenDB. What's the proper way to address this problem?

Matteo Mosca
  • 7,380
  • 4
  • 44
  • 80

3 Answers3

2

You could pass only the 1-A to the controller that recieve the request because PeopleController implies that you are going to work with People and then you can add the prefix to the id using RavenDB functions:

var collectionName = documentStore.Conventions.FindCollectionName(typeof(People));
var idPrefix = documentStore.Conventions.TransformTypeCollectionNameToDocumentIdPrefix(collectionName);

var id = idPrefix +"/"+ "1-A";

Otherwise you could change the id generation convention of that type

Embri
  • 622
  • 3
  • 15
  • This is really not what I'm looking for. I'm working in a decoupled scenario, RavenDB is isolated in the DAL. Entities have and "Id" property, and that's it. If there's a way to have Raven construct my entities when retrieving them from the DB by omitting the prefix, then we're onto something, otherwise we are not. – Matteo Mosca Apr 16 '18 at 15:06
  • how do you load entities? as i said you can change the id generation convention – Embri Apr 17 '18 at 06:32
  • It's not like you say. When you get and Entity (with Query or Load) the "Id" property is populated with the full Id. Also, when you want to query by "Id", you need to pass the full Id. So let's say I load all People to populate a list, then I want to get more info about a specific one. I firstly need the "Id" properties on the list of People to contain the full Id because I will need it again to load the specific Person with Query or Load. – Matteo Mosca Apr 21 '18 at 07:55
2

I have not used ravendb outside of toy projects, but when I read ayendes book, I thought this would be a problem. I see three possible ways to circumvent this:

  1. assign an guid as id, this way you just have no / in your ids. This can be done on document creation
  2. Replace the "/" with something less bad on each controller method, which is annoying and error prone.
  3. Url-escape the id part when generating URLS.

I would use #1 I think.

Christian Sauer
  • 10,351
  • 10
  • 53
  • 85
1

I had the same issue, I changed the document Id generation strategy by GUID. To generate document ID as a GUID you need to pass string.Emptyin you Id property of your entity.

var branch = new Branch.Model.Branch()
{
   Id = string.Empty,
   Name = request.Name,
   Address = request.Address,
   ContactNo = request.ContactNo,
   Email = request.Email
};

await _session.StoreAsync(branch, cancellationToken);
await _session.SaveChangesAsync(cancellationToken);

In RavenDB there are four options supported by the server to store a document and assign an identifier to it https://ravendb.net/docs/article-page/4.1/csharp/server/kb/document-identifier-generation

Niraj Trivedi
  • 2,370
  • 22
  • 24