Open futurist opened 8 years ago
The convention this library uses is that model names should be singular and start with a capital letter (e.g. Formtype
) and the JSON:API types generated from those models will be plural and lowercase (e.g. formtypes
). You can override these conventions if you want to do things differently (see below), but it's usually easier just to follow them.
If you do want to follow them, you need to register your model with with mongoose using a starting capital letter. In other words, it would be:
var formTypeModel = common.db.model('Formtype', formTypeSchema)
instead of
var formTypeModel = common.db.model('formtype', formTypeSchema)
Then, the generated type string will be "formtypes"
, which is the expected value (and which follows the convention used throughout the JSON:API specification).
If you don't like these conventions, though, you can override them, by subclassing the MongooseAdapter, writing your own implementation of the getModelName and getType functions, and then passing an instance of your subclass to the registry. So, in that case, the code:
var adapter = new API.dbAdapters.Mongoose(models);
var registry = new API.ResourceTypeRegistry({
formtype: require('./apidef/formtype'),
}, { dbAdapter: adapter });
would become:
var adapter = new CustomMongooseAdapterSubClass(models);
var registry = new API.ResourceTypeRegistry({
formtype: require('./apidef/formtype'),
}, { dbAdapter: adapter });
Let me know if the approaches above don't work or you have other questions!
Thank you for the quick and detailed reply, it's worked as a charm.
But after tried to subclass the dbAdapters, found it's not very handy to integrate to my existing code coze the whole ES6+Babel thing, but my existing code only use CommonJS.
Can provide an API / option instead of subclassing?
Or, just add option don't change model name, return as is, maybe?
the mongodb collection name also pluralized, how to disable it?
e.g. the person
model became people
collection, if want to keep as is, where can subclassing it? or any option?
But after tried to subclass the dbAdapters, found it's not very handy to integrate to my existing code coze the whole ES6+Babel thing, but my existing code only use CommonJS.
ES6 classes are (for the most part) only sugar around old ES5 patterns, so you don't need to use Babel/ES6 to extend an ES6 class. You just need to create a new constructor function (for the subclass) that has the old constructor function in its prototype chain, and that will return instances that have the old classes' instance methods in their prototype chain. So something like this should work:
function AdapterSubClass() {
return MongooseAdapter.call(this, arguments);
}
AdapterSubClass.getModelName = function() { /* your custom implementation */ }
AdapterSubClass.getType = function() { /* your custom implementation */ }
Object.setPrototypeOf(AdapterSubClass, MongooseAdapter);
Object.setPrototypeOf(AdapterSubClass.prototype, MongooseAdapter.prototype);
var youCustomizedAdapter = new AdapterSubClass(/* standard mongoose adapter options */)
If your curious about more on how/why that code works, this article might be useful.
However, I just realized that there's actually a much simpler way to do this: the MongooseAdapter
class takes as its second argument an inflector, which is then used to do all the pluralization/singularizing. So, if you just pass in an inflector that always returns the string it's given (without pluralizing or singularizing it), that should fix this. In other words:
function identity(it) { return it; }
var adapter = new MongooseAdapter(models, {singular: identity, plural: identity});
Try that and let me know how it goes. I suspect you'll be one of the first users to be using a custom inflector, so you may find a couple bugs (which I'll work to get fixed asap).
the mongodb collection name also pluralized, how to disable it?
This is configured in your mongoose settings for each model and shouldn't have anything to do with the json-api library.
Tried the options:
var adapter = new MongooseAdapter(models, {singular: identity, plural: identity});
all is ok except the model name became uppercase, so person
model will became Person
and throw an error
"Person" has not been registered with the MongooseAdapter
Stack trace:
at MongooseAdapter.getModel (./node_modules/json-api/build/src/db-adapters/Mongoose/MongooseAdapter.js:426:19)
at DocumentationController.getTypeInfo (./node_modules/json-api/build/src/controllers/Documentation.js:148:27)
at ./node_modules/json-api/build/src/controllers/Documentation.js:84:43
at Array.forEach (native)
at new DocumentationController (./node_modules/json-api/build/src/controllers/Documentation.js:83:31)
at Object.<anonymous> (./index.js:30:12)
ok except the model name became uppercase, so person model will became Person and throw an error
The model name shouldn't be being transformed at all once the identity functions are in use.
Check that you're using the same capitalization in every place where you're passing the model. In other words, the models
object that you pass to MongooseAdapter
as its first argument should have a "person"
as its key, if you earlier named the model person
when you registered it with mongoose.model
.
checked all person
is lowercase in ./index.js , ./model/person.js, ./apidef/person.js
When I hardcoded a line in ./node_modules/json-api/build/src/db-adapters/Mongoose/MongooseAdapter.js
file
key: "getModelName",
value: function getModelName(type) {
return type
......
key: "getType",
value: function getType(modelName) {
return modelName
the error gone and things worked.
the api front end always return a "type" field, lost first letter in name
POST /formtype
with below JSON:The returned type become
ormtypes
as below:Source code as below:
./common
contains a mongoose instance./models/formtype.js
file as below:./apiref/formtype.js
file as below:index.js
file as below: