A Mongoose plugin to support JSON:API specification
npm install @stantanasi/mongoose-jsonapi
Add plugin to a schema
import MongooseJsonApi from '@stantanasi/mongoose-jsonapi'
import mongoose, { Schema } from 'mongoose'
const ArticleSchema = new Schema({
title: {
type: String,
required: true,
},
})
ArticleSchema.plugin(MongooseJsonApi, {
type: 'articles',
})
const Article = mongoose.model('Article', ArticleSchema)
import MongooseJsonApi, { JsonApiInstanceMethods, JsonApiModel, JsonApiQueryHelper } from '@stantanasi/mongoose-jsonapi'
import mongoose, { HydratedDocument, Model, Schema, Types } from 'mongoose'
interface IArticle {
_id: Types.ObjectId
title: string
}
type ArticleInstanceMethods = JsonApiInstanceMethods
type ArticleQueryHelper = JsonApiQueryHelper
type ArticleModel = Model<IArticle, ArticleQueryHelper, ArticleInstanceMethods> & JsonApiModel<IArticle>
const ArticleSchema = new Schema<IArticle, ArticleModel, ArticleInstanceMethods, ArticleQueryHelper>({
title: {
type: String,
required: true,
},
})
ArticleSchema.plugin(MongooseJsonApi, {
type: 'articles',
})
type TArticle = HydratedDocument<IArticle, ArticleInstanceMethods, ArticleQueryHelper>
const Article = mongoose.model<IArticle, ArticleModel>('Article', ArticleSchema)
Use methods
const body = {
data: {
type: 'articles',
id: '66e81ea7763111ccc64a104b',
attributes: {
title: 'JSON:API paints my bikeshed!'
}
}
}
const article = Article.fromJsonApi(body)
await article.save()
article._id // '66e81ea7763111ccc64a104b'
article.title // 'JSON:API paints my bikeshed!'
const response1 = article.toJsonApi({
baseUrl: 'http://localhost:5000'
})
response1.jsonapi.version // '1.0'
response1.data.type // 'articles'
response1.data.id // '66e81ea7763111ccc64a104b'
response1.data.links.self // 'http://localhost:5000/articles/66e81ea7763111ccc64a104b'
response1.data.attributes.title // 'JSON:API paints my bikeshed!'
const response2 = await Article.findById('66e81ea7763111ccc64a104b')
.toJsonApi({
baseUrl: 'http://localhost:5000'
})
response2.jsonapi.version // '1.0'
response2.data.type // 'articles'
response2.data.id // '66e81ea7763111ccc64a104b'
response2.data.links.self // 'http://localhost:5000/articles/66e81ea7763111ccc64a104b'
response2.data.attributes.title // 'JSON:API paints my bikeshed!'
const response3 = await Article.find()
.toJsonApi({
baseUrl: 'http://localhost:5000'
})
.paginate({
url: 'http://localhost:5000/articles',
query: {},
})
response3.jsonapi.version // '1.0'
response3.data[0].type // 'articles'
response3.data[0].id // '66e81ea7763111ccc64a104b'
response3.data[0].links.self // 'http://localhost:5000/articles/66e81ea7763111ccc64a104b'
response3.data[0].attributes.title // 'JSON:API paints my bikeshed!'
response3.links.first // 'http://localhost:5000/articles?page[limit]=10&page[offset]=0'
Please refer to the example folder to see how to use it in an Express app
Parameters:
-
type
«String» - The JSON:API resource type for the model
ArticleSchema.plugin(MongooseJsonApi, {
type: 'articles',
})
Parameters:
-
body
«JsonApiBody» - The JSON:API request body
Returns:
- «Document» - The Mongoose Document
const body = {
data: {
type: 'articles',
attributes: {
title: 'JSON:API paints my bikeshed!'
}
}
}
const article = Article.fromJsonApi(body)
article.title // 'JSON:API paints my bikeshed!'
Parameters:
-
opts
«Object» - Options-
opts.baseUrl
«String» - The base URL used in JSON:API links object -
[opts.meta]
«Object» - The meta information to include in the JSON:API response body
-
Returns:
- «JsonApiBody» - The JSON:API response body
const article = new Article({
title: 'JSON:API paints my bikeshed!'
})
const body = article.toJsonApi({
baseUrl: 'http://localhost:5000'
})
body.data.attributes.title // 'JSON:API paints my bikeshed!'
Parameters:
-
sources
«Object | Document» - One or more source objects or documents containing the properties to be applied
Returns:
- «Document» - The Mongoose Document
const people = new People({
firstName: 'John',
lastName: 'Gebhardt',
})
const body = {
data: {
type: 'people',
attributes: {
lastName: 'Doe',
}
}
}
people.merge(People.fromJsonApi(body))
people.firstName // 'John'
people.lastName // 'Doe'
Parameters:
-
relationship
«String» - The name of the relationship to retrieve
Returns:
- «Document | Document[]» - The related Mongoose document(s)
const people = new People({
firstName: 'John',
lastName: 'Doe',
})
await people.save()
const article = new Article({
title: 'JSON:API paints my bikeshed!',
author: people,
})
await article.save()
const author = await Article.findById(article._id).getRelationship('author').exec()
author.firstName // 'John'
author.lastName // 'Doe'
Parameters:
-
query
«JsonApiQueryParams» - The JSON:API Query Parameters
Returns:
- «Query» - The Mongoose Query
// ?include=author,comments&fields[articles]=title&filter[title]=JSON:API paints my bikeshed!&sort=-updatedAt&page[limit]=1
const query = {
include: 'author,comments',
fields: { articles: 'title' },
filter: { title: 'JSON:API paints my bikeshed!' },
sort: '-updatedAt',
page: { limit: 1 }
}
const articles = await Article.find()
.withJsonApi(query)
articles[0].title // 'JSON:API paints my bikeshed!'
Parameters:
-
opts
«Object» - Options-
opts.baseUrl
«String» - The base URL used in JSON:API links object -
[opts.meta]
«Object» - The meta information to include in the JSON:API response body
-
Returns:
- «Query» - The Mongoose Query
const article = new Article({
title: 'Rails is Omakase',
})
await article.save()
const articles = await Article.find()
.toJsonApi({
baseUrl: 'http://localhost:5000'
})
articles.data?.[0].attributes.title // 'Rails is Omakase'
Parameters:
-
opts
«Object» - Options-
opts.url
«String» - The current URL without query parameters -
opts.query
«JsonApiQueryParams» - The current JSON:API Query Parameters
-
Returns:
- «Query» - The Mongoose Query
const articles = await Article.find()
.toJsonApi({
baseUrl: 'http://localhost:5000'
})
.paginate({
url: 'http://localhost:5000/articles',
query: {},
})
articles.links.first // 'http://localhost:5000/articles?page[limit]=10&page[offset]=0'
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the project
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'feat: add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a pull request
This project is licensed under the Apache-2.0
License - see the LICENSE file for details
© 2024 Lory-Stan TANASI. All rights reserved