README
oresm
ObjectResourceMapper - A client ORM for REST APIs
Installation
npm install oresm
Introduction
import User from "./Resources/User"
(async () => {
const user = await User.find(1)
user.username = "newName"
await user.update()
await user.delete()
})()
The above code executes the following requests.
GET /api/users/1
PUT /api/users/1
DELETE /api/users/1
Getting Started
Let's start of by creating a user model.
The following model would create endpoints like
http://127.0.0.1/api/user
import { Model } from "oresm"
class User extends Model {
get host() {
return 'http://127.0.0.1' // defaults to empty string
}
get prefix() {
return 'api' // defaults to empty string
}
get resource() {
// from the example url this is the actual resource part `user`
// defaults to lowercase plualized version of classname, in this case `users`
return 'user'
}
get key() {
// defaults to the key to be used as the identifier. E.g. when you call user.delete() it needs to find the user id to create the endpoint.
return 'id'
}
}
export default User
GET
Getting a collection of documents
const users = await User.get()
GET /api/users
const users = await User.get({ sort: 'name' })
GET /api/users?sort=name
Getting a single document
const user = await User.find(1)
GET /api/users/1
const users = await User.find(1, { xxx: 'yyy' })
GET /api/users/1?xxx=yyy
POST
Use save()
to store a new document.
const user = new User({ // set values in the constructor
name: 'Son Goku',
type: 2,
})
user.type = 3 // set them manually
await user.save({
type: 4, // set them when saving
})
POST /api/users
Once you have retrieved a document, you can perform delete and update operations on it.
DELETE
const user = await User.find(1)
await user.delete()
GET /api/users/1
DELETE /api/users/1
PUT, PATCH
There is more than one way to update a resource, let's look at each individually. Let's imagine the User.find(1)
returns an object that looks like this:
{
id: 1,
username: 'xxx',
type: 1
}
save()
Using Like with POSTing resources, you can use the save()
method to update an existing resource.
const user = await User.find(1)
user.type = 3 // override fields like this
await user.save({
type: 2 // override or add new fields like this
})
GET /api/users/1
PUT /api/users/1
The PUT request sends the following payload:
{
id: 1,
username: 'xxx',
type: 2
}
PATCH
Using We can use patch
to update individual fields.
const user = await User.find(1)
await user.patch({
type: 2
})
GET /api/users/1
PATCH /api/users/1
It sends the following payload
{
type: 2
}
Computed / virtual fields
Let's go back to our user example
const user = await User.find(1)
if (user.type === 2) { // if user is admin
// do something
}
While this works, there is a much cleaner way of doing this. We can use the User
object we created to have computed fields.
import ObjectResourceMapper from "./ObjectResourceMapper"
class User extends ObjectResourceMapper {
get isAdmin() {
return this.type === 2
}
}
export default User
And back to our script from before
const user = await User.find(1)
if (user.isAdmin) {
// do something
}
Of course you can move other logic to the model as well.
Get raw data
Getting the raw data is easy.
const user = await User.find(1)
const userData = user.getEntity()
Configure fetch
For available configurations please check out https://github.com/MZanggl/fetch-me-json
import { configureFetch } from 'oresm'
const configurations = {}
configureFetch(configurations)
Limitations
You can not dynamically add new fields.
const user = new User({
name: 'Son Goku',
})
user.type = 3 // add new field
await user.save() // will not insert `type`
This could be solved using proxies in the future. As a workaround you should do
const user = new User({
name: 'Son Goku',
})
await user.save({
type: 3,
})