krakenjs / swaggerize-express

Design-driven apis with swagger 2.0 and express.
Other
355 stars 81 forks source link

Using paraType body/form #18

Closed hans-d closed 10 years ago

hans-d commented 10 years ago

can you provide some examples using paramType body and form, pref in combination with express 4?

re the body I can get some to work:

the form is where I fail to get it working...

tlivings commented 10 years ago

Can you provide your definition for the param? Also relevant code?

expected: required body missing is because the data you are posting is empty.

tlivings commented 10 years ago

For example, this works for me:

"parameters": [
    {
        "name": "body",
        "description": "some form data",
        "required": true,
        "type": "string",
        "paramType": "body"
    }
]
$ curl --data "hello world" -H "Content-Type:text/plain" <url>
hans-d commented 10 years ago

See also #19 . Try running: curl --data "" -H "Content-Type:text/plain" <url> on your example and you will receive a Error: invalid type: object (expected string).

tlivings commented 10 years ago

Providing an empty value causes express to assign it as an object. The bug, if there is one, is in express:

https://github.com/expressjs/body-parser/blob/master/lib/types/text.js#L51

hans-d commented 10 years ago

yup, see also my issue logged there (https://github.com/expressjs/body-parser/issues/44) and their response. Hence #19 to turn {} into an empty string.

dougwilson commented 10 years ago

Can you post the full verbose output from curl <url> -v -d "" -H 'Content-Type: text/plain' -X POST, please?

hans-d commented 10 years ago

output with -d "":

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)
> POST /api/test HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:3000
> Accept: */*
> Content-Type: text/plain
> Content-Length: 0
> 
< HTTP/1.1 400 Bad Request
< X-Powered-By: Express
< Content-Type: application/json; charset=utf-8
< Content-Length: 57
< Date: Fri, 05 Sep 2014 16:46:52 GMT
< Connection: keep-alive
* HTTP error before end of send, stop sending
< 
* Closing connection 0
{"error":"Error: invalid type: object (expected string)"}

output with -d "x":

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)
> POST /api/test HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:3000
> Accept: */*
> Content-Type: text/plain
> Content-Length: 1
> 
* upload completely sent off: 1 out of 1 bytes
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 7
< Date: Fri, 05 Sep 2014 16:55:47 GMT
< Connection: keep-alive
< 
* Connection #0 to host 127.0.0.1 left intact
hi post

app.coffee:

express = require 'express'
api = require './api'
bodyParser = require 'body-parser'

apiRouter = api { spec: 'app/api/spec.yaml', docUrl: '/api-docs' }

errorHandler = (err, req, res, next) ->
    if err and res.statusCode
        res.send { error: err.toString() }
    else
        res.status('500').send err || 'oh oh'
        console.log err.stack

app = express()
app.set 'port', process.env.PORT || 3000
app.use bodyParser.text()
app.use apiRouter
app.use errorHandler

app.listen app.get('port'), () ->
    apiRouter.setUrl 'http://localhost:' + app.get 'port'
    console.log 'listening on ' + app.get 'port'

api/index.coffee:

swaggerize = require 'swaggerize-express'
yaml = require 'js-yaml'
fs = require 'fs'
handlers = require './handlers.coffee'

readApi = (file) ->
    raw = fs.readFileSync file
    yaml.safeLoad raw

module.exports = (options) ->
    swaggerize
        api: readApi options.spec
        docspath: options.docUrl
        handlers: handlers

api/handlers.coffee:

module.exports =
    test:
        $post: (req, res) ->
            console.log 'test!', req.params, '['+req.body+']'
            res.send 'hi post'

api/spec.yaml:

---

apiVersion: '0.0.0'
swaggerVersion: '1.2'

basePath: 'http://localhost:8000/'
resourcePath: '/api'

apis:

  - path: "/test"
    operations:
      - nickname: test
        type: string
        method: POST
        parameters:
          - name: body
            required: true
            type: string
            paramType: body
dougwilson commented 10 years ago

Thanks. Looks like the issue is actually deep down within the type-is module.

dougwilson commented 10 years ago

FYI I filed an issue as https://github.com/jshttp/type-is/issues/9 to remind myself about this, and then https://github.com/expressjs/body-parser/issues/44 will track when it makes it's way into body-parser module.

tlivings commented 10 years ago

Fixed in 1.0.0-rc.4

tlivings commented 10 years ago

Thanks @dougwilson !

dougwilson commented 10 years ago

Just wanted to post an update on here that body-parser@1.8.0 should be setting req.body = '' when an empty body is sent to the server now.

tlivings commented 10 years ago

Awesome, thanks!

jasisk commented 10 years ago

We were stung by this (meaning, empty body being an empty plain object) at some point recently in one of the kraken modules. I recall we put in place some sort of workaround. Anyone remember where that was? I can (and will) dig around a bit but wanted to see if anyone knew off the top of their head before I did.