tether / manner Goto Github PK
View Code? Open in Web Editor NEWCreate HTTP services in the best possible manner
License: MIT License
Create HTTP services in the best possible manner
License: MIT License
If the data returned by a service is not a stream, we could gzip it.
We should be able to return objects (in addition of string, buffer, streams or promises). It seems like it is not working.
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
}
}
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() {
}
}))
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.
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'))
}
}
manner returns a 500 status code, nothing is logged.
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
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.
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.
Use schema to define the content type of services.
We should be able to catch promises that are rejected (or errors on streams).
{
get() {
// do something
}
}
{
'get': {
'/:name': () => {},
/:name/:id: '/other/localpath'
}
}
We could also return status code directly, redirect or proxy the url.
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.
const service = manner()
service.get()
service.post()
service.routes()
service.alias()
service.redirect()
service.auth()
service.validate()
{
get() {
// get schema for this HTTP method
this.schema()
},
post() {
// get method GET defined above
this.get('/')
}
}
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.
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)
get() {
return status(301, 'http://example.com')
}
Take example on express:
We should handle unknown methods
We should be able to trigger errors and capture/propagate status code to the HTTP response.
const api = manner(/* something */)
api(req, res)
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.
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'
}
})
We should support middleware a bit like express.
const app = service()
app.get('/hello', middleware1, middleware2, (query, data) => {
return 'something'
})
HTTP options returns the allowed methods. We could read the options method or Array) when creating the service to restrict access.
See HTTP OPTIONS
We should double check if we need to interrupt the request (close it) on error.
If a service returns a promise that resolves to a stream, we should pipe the stream to the response.
We should test the HTTP errors triggered if route does not exist.
node> require('url').parse('/status?name=ryan', true)
{ href: '/status?name=ryan',
search: '?name=ryan',
query: { name: 'ryan' },
pathname: '/status' }
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 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.
Automatically transform body type into raw object
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.
We should be able to add sub routes programmaticaly.
var api = manner({
post() {}
})
api.use('/super', manner({
get: () => {}
})
It would be great if a manner service could be used as an express app.
var app = express()
app.use('/', manner(service))
We should properly catch errors and send payload with it. Unknow errors should return forbidden and a reason.
IS it possible to create a transform stream and have access to the request properties?
request.pipe(api).pipe(response)
We should send more details in the error payloads. We should also look at the status code and make sure they make sense.
Returning an error in a service method would send the status through the response. Returning null/undefined should return a 200 Ok.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.