Giter VIP home page Giter VIP logo

manner's People

Contributors

bredele avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

joeyhops

manner's Issues

Optimization

  • Body parsing should not be done for GET
  • SCHEMA should be pre compiled
  • compare Object.keys to for in (for manner, isokay, etc)

Service returning object

We should be able to return objects (in addition of string, buffer, streams or promises). It seems like it is not working.

Schema and private properties

Documentation can be generated from the schema and sometimes schema can be useful for internal machinery. Having an attribute private could tell the generator to leave an attribute out of the doc.

        test: {
          private: true,
          description: `
            This is some description to make sure this parameters can not be overriden.
          `,
          transform() {
            return null
          }
        }

function as service

Manner should accept a function as a service.

manner(function(req, res) {

})

and return a stream. It would be usefule for the module manner-folder and manner-jwt where we could programmaticaly define a service that has to be authenticated.

manner(jwt({
  get() {

  }
}))

Schema and query/body parsing

We could use the schema to conditionally parse the query/body content.

{
  post: {
    '/': {
      query: false,
      body: false
     }
  }
}

Also we could merge a default schema with the one provided.

automatically log errors when returned Promises reject and 500 status is returned

It would be nice if there was some automatic logging of errors when a 500 status is returned.

module.exports = {
  post() {
    return Promise.reject(new Error('something went wrong'))
  }
}

Current behaviour:

manner returns a 500 status code, nothing is logged.

Desired behaviour:

In addition to returning a 500 status code, provide some automatic logging of the error -- the route, the parameters and body, and the error itself.

Something like

manner error (500) while responding to /foo/bar
parameters: {
  bar: 'baz'
}  
body: {
  stuff: 'more-stuff'
}
Error: Cannot fizz the zipzap
  at zipzap.fizz (/path/to/zipzap.js)
  .... rest of stack trace

Motivation:

It seems from this discussion on software engineering stack exchange that's it's a good practice to be logging them. (The questions itself isn't strictly related, but the answers address exceptions and logging in general and so they seem to apply here -- especially if you consider the server backed by manner as one component in a bigger integrated system that depends on its results). It would be nice to have errors logged automatically when we return a 500 status code instead of leaving it up to the implementor of each method to log explicitly.

The alternative is to manually add .catch(error => { log(error); throw error }) at the end of each method, but that's a lot of duplication and doesn't give the same context that I'm suggesting.

Define media type allowed

We should be able to define the media types allowed in case the client request a format not supported, we can return the 406 code.

Reject promises

We should be able to catch promises that are rejected (or errors on streams).

Custom paths and redirects, proxy, etc

{
  get() {
    // do something
  }
}

 
{
  'get': {
    '/:name': () => {},
    /:name/:id: '/other/localpath'
  }
}

We could also return status code directly, redirect or proxy the url.

Resolve path

It should not resolve path if method is not dynamic. For example, /people/user/nope/k/k/kk/k/k/k/k/k/k should not resolve to /people/user except if there is a dynamic route that match the URL.

Programatic API

const service = manner()
service.get()
service.post()
service.routes()
service.alias()
service.redirect()
service.auth()
service.validate()

Scope access and schema

{
  get() {
   // get schema for this HTTP method
    this.schema()
  },

  post() {
    // get method GET defined above
    this.get('/')
  }
}

Manner core HTTP free

We should think about creating a duplex stream that is independent from HTTP requests.

var api = manner({})

// somewhere in a http server
input(req, res)
  .pipe(api)
  .pipe(res)

It might be in a separate module. This would allow to be transport free.

secret methods

It would be able to define routes that are only available through the programmatic API (not HTTP)

service({
  options: {
    get: ['/hellosecet']
  },
  get: {
    '/hello': () => 'hello',
    '/hellosecret': () => 'secret'
  }
})

At any time we could make a method available with HTTP (useful for testing or simply for consistency). Let's try to find an elegant API to enable this feature (maybe through HTTP options - let's remember that the OPTIONS method will be automatically generated from the methods available)

HTTP status code + error

We should be able to trigger errors and capture/propagate status code to the HTTP response.

const api = manner(/* something */)
api(req, res)

Content type from schema

Now that manner services are truly asynchronous, the content type should be set from manner promises and not from salute. This way we could set content type from scherma.

authentication

We should be able to create authenticated services.

service({
  auth: () => {
    // authenticate request (should know the authentication type by default and parse the request
    // automatically)
  },
  get: () => 'something based on authentication'
})

or hand pick which methods should be authenticated:

service({
  auth: {
    get: () => 'return something'
  }
})

middleware

We should support middleware a bit like express.

const app = service()

app.get('/hello', middleware1, middleware2, (query, data) => {
  return 'something'
})

HTTP OPTIONS

HTTP options returns the allowed methods. We could read the options method or Array) when creating the service to restrict access.

See HTTP OPTIONS

Response and promise

If a service returns a promise that resolves to a stream, we should pipe the stream to the response.

Get query object from module URL

node> require('url').parse('/status?name=ryan', true)
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: { name: 'ryan' },
  pathname: '/status' }

throw http status on content-type missing

We get the content type using the module content-type

contentType(req).type

This module trigger a TypeError if the content-type does not exist or is not supported. We should use that error to trigger a HTTP MediaType error.

Manner with native schema

Manner could define as many nested routes as wanted and could contain schema. Here's an example:

{
  get: {
    '/': {
      route: () => {},
      data: {
        name: {
          required: true
        }
      },
      '/hello': {
      
      }
    }
  }
}

if a path is an object it contains schema and/or sub routes. If it's a function it is a shortcut for the route prop.

Body type

Automatically transform body type into raw object

Schema and programmatic API

Should we apply schema for the programmatic API?

api.get('/', {
  name: 'bob'
})

It would mean that the programmatic API should also return a stream (or promise). Except if the schema library we are using does not return a promise.

Manner and express-like API

We should be able to add sub routes programmaticaly.

var api = manner({
  post() {}
})

api.use('/super', manner({
  get: () => {}
})

Manner and express

It would be great if a manner service could be used as an express app.

var app = express()

app.use('/', manner(service))

Catch error and send status

We should properly catch errors and send payload with it. Unknow errors should return forbidden and a reason.

Errors payload

We should send more details in the error payloads. We should also look at the status code and make sure they make sense.

Return error (status) or null

Returning an error in a service method would send the status through the response. Returning null/undefined should return a 200 Ok.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.