2

I'm coding a website using Swagger 3.0/OpenAPI to describe my APIs, and Node.js for the back-end. I successfully made the GET requests work but I'm having some trouble with all the POST requests. The problem is that the parameters I provide from an HTML form while performing the POST request seem not to be received by the auto-generated by Swagger handlers in the /controllers folder. In particular, the req.swagger.params array and req.swagger.params['body'], sub-fields of the HTTP request object, that is supposed to contain the parameters, are always empty.

I tried to use both 'application/x-www-form-urlencoded' and 'application/json' as ContentType; I tried different sources to perform the request such as the SwaggerUI, Postman, the front-end web page and CURL; I tried both the FetchAPI and JQuery AJAX ($.post and $.ajax).

Here it's how I perform the POST request in Register.js:

event.preventDefault();

var firstname = $('#inputFirstname').val();
var lastname = $('#inputLastname').val();
var email = $('#inputEmail').val();
var psw = $('#inputPassword').val();

var data = {
    'firstname': firstname,
    'lastname': lastname,
    'email': email,
    'password': psw
};

$.ajax({
    url: '/user/register',
    type: 'POST',
    dataType: 'text', // also tried json
    contentType: 'application/x-www-form-urlencoded', //also tried json
    data: data
       }
)
 .done(successScreen)
 .fail(() => console.log('Fail'));

Here it's how I describe my API in swagger.yaml:

(...)
/user/register:
    post:
      tags:
      - user
      summary: Create a new user.
      description: Register into the store.
      operationId: userRegisterPOST
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/RegisterBody'
      responses:
        201:
          description: succesfull registration
          content: {}
      x-swagger-router-controller: User
(...)
RegisterBody:
      required:
      - email
      - firstname
      - lastname
      - password
      type: object
      properties:
        email:
          type: string
        password:
          type: string
        firstname:
          type: string
        lastname:
          type: string

Here it's the auto-generated handler in /controllers/User.js for the POST requests on /user/register:

49:module.exports.userRegisterPOST = function userRegisterPOST (req, res){
50:  var body = req.swagger.params['body'].value; // here it's where I get the error, but it's auto-generated code
51:  User.userRegisterPOST(body)
52:    .then(function (response) {
53:      utils.writeJson(res, response);
54:    })
55:    .catch(function (response) {
56:      utils.writeJson(res, response);
57:    });
58:};

The error I get is:

TypeError: Cannot read property 'value' of undefined
    at userRegisterPOST (/.../controllers/User.js:50:41)
    at swaggerRouter (/.../node_modules/oas3-tools/middleware/swagger-router.js:388:20)
    at Layer.handle [as handle_request] (/.../node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/.../node_modules/express/lib/router/index.js:317:13)
    at /.../node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/.../node_modules/express/lib/router/index.js:335:12)
    at next (/.../node_modules/express/lib/router/index.js:275:10)
    at /.../node_modules/oas3-tools/middleware/swagger-validator.js:388:30
    at /.../node_modules/async/dist/async.js:1140:9
    at /.../node_modules/async/dist/async.js:473:16
    at eachOfArrayLike (/.../node_modules/async/dist/async.js:1057:9)
    at eachOf (/.../node_modules/async/dist/async.js:1117:5)
    at _asyncMap (/.../node_modules/async/dist/async.js:1133:5)
    at Object.map (/.../node_modules/async/dist/async.js:1122:16)
    at swaggerValidator (/.../node_modules/oas3-tools/middleware/swagger-validator.js:358:15)
    at Layer.handle [as handle_request] (/.../node_modules/express/lib/router/layer.js:95:5)

I'm supposed to find the params in req.swagger.params['body'].value as for all the GET request.

Mattia
  • 23
  • 1
  • 8

2 Answers2

0

Finally, I solved switching from 'oas3-tools' to ‘oas-tools’ (https://github.com/isa-group/oas-tools) to manage OpenAPI 3.0 APIs. With this new Node module, I'm able to retrieve the POST parameters in req.body.

Mattia
  • 23
  • 1
  • 8
  • Maybe a bit more about how you did this might help the rest of us, Thanks – Erik Grosskurth Jul 18 '19 at 03:13
  • Sure. There’s no much more to say. However, after almost a week reading the oas3-tools doc (https://www.npmjs.com/package/oas3-tools) I didn’t figure out what the problem was; so I decided to change the npm module to manage my Swagger/OpenAPI 3.0 APIs. I choose the oas-tools module because its doc is quite better that the first one. This way I was able to retrieve all the POST parameters in the subfield ‘body’ of the obj ‘req’ passed to you APIs controllers (check req’s structure with the debug mode). It’d be useful if someone could figure out what the problem was with the old npm module. – Mattia Jul 18 '19 at 09:00
  • I have decided to abandon Swagger altogether... Seems much easier and scalable to just create JSON definitions and middleware tools to build out validation, auth and documentation without being reliant on third parties to properly manage their dependencies. I have been working with swagger for almost a year now and I am very disappointed. – Erik Grosskurth Jul 18 '19 at 16:12
0

You can continue using Swagger's interface to create your API, but don't create your sources from there.

Save your "swagger.yaml" file to your project's folder, for instance, "C:\myproject", and then, type:

oas-generator swagger.yaml myproject

Installation of oas-generator:

npm install oas-generator -g

Important: read the docs carefully: https://github.com/isa-group/oas-tools

A more robust OAS 2.x/3.x generator: https://github.com/OpenAPITools/openapi-generator