<NME> deserialize.js
<BEF> 'use strict';
var _ = require('lodash');

module.exports = function (app) {
  var remotes = app.remotes();

  function deserializeJSONAPIPayload (ctx, next) {

    var regexs = [
      /\.create/,
    var data, serverRelations, errors

    if (utils.shouldNotApplyJsonApi(ctx, options)) {
      return next()
    }

    var regexs = [/^create$/, /^updateAttributes$/, /^patchAttributes$/]

    var matches = regexs.filter(function (regex) {
      return regex.test(ctx.method.name)
    })

    /**
     * Handle include relationship requests (aka sideloading)
     */
    if (RelUtils.isRequestingIncludes(ctx)) {
      ctx.res.set({ 'Content-Type': 'application/vnd.api+json' })

      ctx.req.isSideloadingRelationships = true

      if (RelUtils.isLoopbackInclude(ctx)) {
        return next()
      }

      if (!RelUtils.shouldIncludeRelationships(ctx.req.method)) {
        return next(RelUtils.getInvalidIncludesError())
      //transform the payload
      ctx.args.data = data.data.attributes || {};
      //TODO: Rewrite to normal search model by type and FK
      var relations = data.data.relationships;
      if (_.isPlainObject(relations)) {
        _.each(relations, function (relationData, relation) {
          var fk = relation + 'Id'; //replace on FK from model
          ctx.args.data[fk] = relationData.data.id;
        });
      }
    }

    next();
  }

  //register a handler to run before all remote methods so that we can
  //transform JSON API structured JSON payload into something loopback
  //can work with.
  remotes.before('**', deserializeJSONAPIPayload);
};

      // transform the payload
      deserializer(options, function (err, deserializerOptions) {
        if (err) return next(err)

        options.data = deserializerOptions.data
        ctx.args.data = deserializerOptions.result

        options.debug('======================')
        options.debug('Deserializer output   ')
        options.debug('======================')
        options.debug(
          'DESERIALIZED RESULT  |:',
          JSON.stringify(deserializerOptions.result)
        )
        next()
      })
    } else {
      next()
    }
  })
}

/**
 * Check for errors in the request. If it has an error it will return a string, otherwise false.
 * @private
 * @memberOf {Deserialize}
 * @param {Object} data
 * @param {String} requestMethod
 * @return {String|false}
 */
function validateRequest (data, requestMethod) {
  if (!data.data) {
    return 'JSON API resource object must contain `data` property'
  }

  if (!data.data.type) {
    return 'JSON API resource object must contain `data.type` property'
  }

  if (['PATCH', 'PUT'].indexOf(requestMethod) > -1 && !data.data.id) {
    return 'JSON API resource object must contain `data.id` property'
  }

  return false
}

<MSG> Added create relation

<DFF> @@ -1,10 +1,14 @@
 'use strict';
 var _ = require('lodash');
+var inflection = require('inflection');
 
 module.exports = function (app) {
   var remotes = app.remotes();
+  //register a handler to run before all remote methods so that we can
+  //transform JSON API structured JSON payload into something loopback
+  //can work with.
 
-  function deserializeJSONAPIPayload (ctx, next) {
+  remotes.before('**', function (ctx, next) {
 
     var regexs = [
       /\.create/,
@@ -37,20 +41,47 @@ module.exports = function (app) {
       //transform the payload
       ctx.args.data = data.data.attributes || {};
       //TODO: Rewrite to normal search model by type and FK
-      var relations = data.data.relationships;
-      if (_.isPlainObject(relations)) {
-        _.each(relations, function (relationData, relation) {
-          var fk = relation + 'Id'; //replace on FK from model
-          ctx.args.data[fk] = relationData.data.id;
+      var clientRelations = data.data.relationships;
+      var serverRelations = this.definition.settings.relations;
+      if (_.isPlainObject(clientRelations)) {
+        _.each(clientRelations, function (clientRelation, clientRelationName) {
+          var serverRelation = serverRelations[clientRelationName];
+
+          if (_.isPlainObject(serverRelation)) {
+            var relationType = null;
+            var relationValue = null;
+            var fkSuffix = null;
+            var fk = null;
+            if (_.isArray(clientRelation.data)) {
+              relationType = _.result(_.find(clientRelation.data, 'type'), 'type');
+              relationValue = _.map(clientRelation.data, function (val) {
+                return val.id;
+              });
+              fkSuffix = 'Ids';
+            } else {
+              relationType = clientRelation.data.type;
+              relationValue = clientRelation.data.id;
+              fkSuffix = 'Id';
+            }
+
+            relationType = inflection.singularize(relationType);
+         
+            if (relationType === serverRelation.model) {
+              if (serverRelation.foreignKey) {
+                fk = serverRelation.foreignKey;
+              } else {
+ 
+                relationType = inflection.camelize(relationType, true);
+                fk = relationType + fkSuffix;
+              }
+              console.log(fk, relationValue);
+              ctx.args.data[fk] = relationValue;
+            }
+          }
         });
       }
     }
 
     next();
-  }
-
-  //register a handler to run before all remote methods so that we can
-  //transform JSON API structured JSON payload into something loopback
-  //can work with.
-  remotes.before('**', deserializeJSONAPIPayload);
+  });
 };

Added create relation