Loopback-next: Support exploded form query strings

Created on 19 Jan 2020  路  2Comments  路  Source: strongloop/loopback-next

Suggestion

Currently, LoopBack 4 (lb4) only supports exploded and JSON-encoded deepObject query strings. However, this means that a typical HTML <form> or existing software cannot directly interact with the API without modifications to how it constructs the URL.

Hence, lb4 should support ampersand-delimited, exploded form query strings as it is a more commonly-used encoding.

Whilst this encoding prevents nested objects, it's simplicity can allow for easier adoption of lb4.

Use Cases

  • Easier adoption of lb4
  • More transparent replacement of existing API infrastructures with lb4
  • Simpler API client/consumer design
  • Easier adoption of lb4 for new users

Examples

As per-OpenAPI 3.0.1 - Style Values, an API client and server can use a more commonly-used query string format for HTML <forms> and other software.

For example, a pizza ordering form using the <form> HTML tag with the following fields:

  • Type (select)
  • Toppings (radio, multiple)
  • reCaptcha session (string)

This can result in the following query string:

?type=cheesy&toppings=pepperoni&toppings=pineapple&recaptcha=[removed for brevity]

Acceptance criteria

  • [ ] - Update LoopBack documentation to include examples of form query strings , which are already supported by the default @param() decorator.
REST feature help wanted

Most helpful comment

I am not sure how often are HTML forms submitting the data via a query string? I think it's more common to submit form data in the body of a POST request.

I.e. instead of sending a application/json request body {"type": "cheesy", "toppings": "pepperoni", "toppings": pineapple}, the client can send application/x-www-form-urlencoded body type=cheesy&toppings=pepperoni&toppings=pineapple.

This is something we support in LoopBack 3, it makes a lot of sense to me to support this variant in LB4 too.

Having said that, I can also see how it would be nice to be able to collect several query string parameters into a single TypeScript argument. For example, instead of the current approach where a query filter is specified as GET /products?filter[where][name]=Pen&filter[limit]=10, we can support GET /products?where[name]=Pen&limit=10.

All 2 comments

@achrinza this format is supported as default. For instance, I created the default ping app with lb4 app and edited the ping() method as follows, the query http://localhost:3000/ping?count=0&count2=2 works. Looks like this is not explained enough in the examples and docs. I will use this issue to update docs.

/**
 * A simple controller to bounce back http requests
 */
export class PingController {
  constructor(@inject(RestBindings.Http.REQUEST) private req: Request) {}

  // Map to `GET /ping`
  @get('/ping', {
    responses: {
      '200': PING_RESPONSE,
    },
  })
  ping(@param({name: 'count', in: 'query'},
  ) count: number,
  @param({name: 'count2', in: 'query'},
  ) count2: number): object {
    // Reply with a greeting, the current time, the url, and request headers
    return {
      count: count,
      count2: count2,
      greeting: 'Hello from LoopBack',
      date: new Date(),
      url: this.req.url,
      headers: Object.assign({}, this.req.headers),
    };
  }
}

I am not sure how often are HTML forms submitting the data via a query string? I think it's more common to submit form data in the body of a POST request.

I.e. instead of sending a application/json request body {"type": "cheesy", "toppings": "pepperoni", "toppings": pineapple}, the client can send application/x-www-form-urlencoded body type=cheesy&toppings=pepperoni&toppings=pineapple.

This is something we support in LoopBack 3, it makes a lot of sense to me to support this variant in LB4 too.

Having said that, I can also see how it would be nice to be able to collect several query string parameters into a single TypeScript argument. For example, instead of the current approach where a query filter is specified as GET /products?filter[where][name]=Pen&filter[limit]=10, we can support GET /products?where[name]=Pen&limit=10.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shahulhameedp picture shahulhameedp  路  3Comments

frodoe7 picture frodoe7  路  3Comments

teambitcodeGIT picture teambitcodeGIT  路  3Comments

zero-bugs picture zero-bugs  路  3Comments

mhdawson picture mhdawson  路  3Comments