Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discussion: custom PouchDB Server builds #234

Open
gr2m opened this issue Jun 15, 2017 · 4 comments
Open

Discussion: custom PouchDB Server builds #234

gr2m opened this issue Jun 15, 2017 · 4 comments

Comments

@gr2m
Copy link
Contributor

gr2m commented Jun 15, 2017

⚠️ This is just me dreamcodin. The code shown here doesn’t exist, it’s just meant as a base for discussion

I would like to create a custom server which exposes only the CouchDB APIs that I need, similar to PouchDB’s custom builds which only have the features that I need.

const PouchDB = require('PouchDB')
const express = require('express')
const app = express()

app.get('/', function (req, res) {
  res.status(200).send({
	  'my-custom-couch': 'Welcome!'
  })
})

app.use(require('@pouchdb-server/express-core')(PouchDB))
app.use(require('@pouchdb-server/express-db')(PouchDB))
app.use(require('@pouchdb-server/express-document')(PouchDB))
app.use(require('@pouchdb-server/express-changes')(PouchDB))
app.use(require('@pouchdb-server/express-attachments')(PouchDB))

app.listen(3000, function () {
  console.log('Listening on port 3000!')
})

A package like pouchdb-express-router could then be implemented like this

const Router = require('express').express.Router

module.exports = function (PouchDB) {
  const router = Router()
  
  router.use(require('@pouchdb-server/express-core')(PouchDB))
  router.use(require('@pouchdb-server/express-db')(PouchDB))
  router.use(require('@pouchdb-server/express-document')(PouchDB))
  router.use(require('@pouchdb-server/express-changes')(PouchDB))
  router.use(require('@pouchdb-server/express-attachments')(PouchDB))
  
  return router
}

and be used like this

const PouchDB = require('PouchDB')
const express = require('express')
const app = express()

app.get('/', function (req, res) {
  res.status(200).send({
	  'my-custom-couch': 'Welcome!'
  })
})

app.use(require('express-pouchdb-router')(PouchDB))

app.listen(3000, function () {
  console.log('Listening on port 3000!')
})

An "all inclusive" express middleware could be published as @pouchdb-server/express

Dreaming @pouchdb-server/security & @pouchdb-server/express-security

Just as it is today, I would like to separate logic like CouchDB’s security into two packages:

  1. @pouchdb-server/security
    A generic module with APIs needed for security. It uses the passed PouchDB to persist and lookup security settings
  2. @pouchdb-server/express-security
    An express middleware which uses the security module in its route handlers. The logic in the route handlers should be minimal, the bulk of the work should happen in the security module

@pouchdb-server/express-security would look something like this

const Security = require('@pouchdb-server/security')
const Router = require('express').Router

module.exports = function (PouchDB) {
  const router = new Router()
  const security = new Security(PouchDB)

  app.use('/:db(/*)?', function (req, res) {
    security.check(req.params.db, next)
  })

  app.get('/:db/_security', function (req, res) {
    security.get(req.params.db, (error, settings) => {
      // I don’t know express error handling works
      // I’d expect we could define a general error handler
      // in @pouchdb-server/express-core
      if (error) throw error

      res.send(settings)
    })
  })

  app.put('/:db/_security', require('body-parser'), function (req, res) {
    security.update(req.params.db, req.body, (error, settings) => {
      // I don’t know express error handling works
      // I’d expect we could define a general error handler
      // in @pouchdb-server/express-core
      if (error) throw error

      res.send({ok: true})
    })
  })
}

@pouchdb-server/security would keep a local cache of the current database security setting for faster lookup. It could store the security setting internally in a _local/security document.

I’m sure there is lot of things I did not consider. But I think it would be good to get a conversation going of where we want to go with PouchDB Server. And this is my input :)

@gr2m
Copy link
Contributor Author

gr2m commented Jun 17, 2017

@garrensmith
Copy link
Member

@gr2m I like the ideas here. The big thing for me is that the PouchDB core team is really small. So any changes we do to PouchDB-server need to make it easier to maintain. Ideally pouchdb-server needs to be a super thin layer on top of PouchDB.

@gr2m
Copy link
Contributor Author

gr2m commented Jun 19, 2017

I want to help maintaining PouchDB Server and agree 💯

@marten-de-vries
Copy link
Member

It's hard to split pouchdb-server up into a bunch of independent routes. I tried, the current 'mode' functionality which allows for enabling/disabling stuff but still keeps everything inside the express-pouchdb module was the best I could do. I don't remember the details, but there is just too much shared state between modules necessary IIRC. The most obvious one being the configuration and a (wrapped) PouchDB object, but there's probably more.

It might actually be easier to do this when building it on top of pouchdb-express-router. But that does mean doing away with some couchdb compatibility, and it hasn't been updated recently so there's probably still a couple of bugs (pouchdb/pouchdb-express-router#5).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants