Skip to content

Conversation

@kadamwhite
Copy link
Collaborator

In response to #299, #312, and #314, this introduces a new .setHeaders() prototype method for both WPAPI and WPRequest. .setHeaders() allows a single WPRequest, or all requests generated from a WPAPI site client instance, to be augmented with one or more custom HTTP headers. Providing this functionality allows consumers of the wpapi library to utilize custom authentication schemes (such as JWT) with the Authentication header, to specify the preferred language of the response endpoints with the Accept-Language header, and so on. Providing a general-purpose interface is preferred in place of specifically implementing individual methods for JWT auth, language preferences, or other specific headers that a consumer of this library may want to send.

Closes #299, fixes #312, fixes #314

Usage:

If you need to send additional HTTP headers along with your request (for example to provide a specific Authorization header for use with alternative authentication schemes), you can use the .setHeaders() method to specify one or more headers to send with the dispatched request:

// Specify a single header to send with the outgoing request
wp.posts().setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' )...

// Specify multiple headers to send with the outgoing request
wp.posts().setHeaders({
    Authorization: 'Bearer xxxxx.yyyyy.zzzzz',
    'Accept-Language': 'pt-BR'
})...

You can also set headers on the WPAPI instance itself, which will then be used for all subsequent requests created from that site instance:

wp.setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' );
wp.users().me()...
wp.posts().id( unpublishedPostId )...

In response to #299, #312, and #314, this introduces a new .setHeaders()
prototype method for both WPAPI and WPRequest. `.setHeaders()` allows a
single WPRequest, or all requests generated from a WPAPI site client
instance, to be augmented with one or more custom HTTP headers. Providing
this functionality allows consumers of the wpapi library to utilize
custom authentication schemes (such as JWT) with the Authentication
header, to specify the preferred language of the response endpoints with
the Accept-Language header, and so on. Providing a general-purpose
interface is preferred in place of specifically implementing individual
methods for JWT auth, language preferences, or other specific headers
that a consumer of this library may want to send.

Closes #299, fixes #312, fixes #314

**Usage:**

If you need to send additional HTTP headers along with your request
(for example to provide a specific `Authorization` header for use with
alternative authentication schemes), you can use the `.setHeaders()`
method to specify one or more headers to send with the dispatched request:

```js
// Specify a single header to send with the outgoing request
wp.posts().setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' )...

// Specify multiple headers to send with the outgoing request
wp.posts().setHeaders({
    Authorization: 'Bearer xxxxx.yyyyy.zzzzz',
    'Accept-Language': 'pt-BR'
})...
```

You can also set headers on the WPAPI instance itself, which will then
be used for all subsequent requests created from that site instance:

```js
wp.setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' );
wp.users().me()...
wp.posts().id( unpublishedPostId )...
```
@kadamwhite
Copy link
Collaborator Author

Feedback is welcome on this interface, especially the method's name: I stuck with setHeaders for clarity, but I am not convinced it is the best option; .set() feels too general, and .headers() I'm concerned will be confused with the existing request instantiator method .head().

@gnarf
Copy link
Collaborator

gnarf commented May 17, 2017

I think setHeaders seems fine here.

I might entertain something like .config({ headers: {} }) also, as there will likely be other similar configuration options you'll need to set with requests like { credentials: 'include' } from the fetch api or cache etc, not all of witch are request headers.

@mzalewski
Copy link

Looks great, easy to understand and use. I don't have any complaints about the name, "setHeaders" is descriptive and makes sense.

@mzalewski
Copy link

Also, have you considered allowing a callback as a parameter? Just thinking from an OAuth1 point of view:

wp.posts().setHeaders(function(method, url, params) { return { 'Authorization': generateOAuth1Signature(method, url, params) } })

( Sorry if this isn't the right place for this comment )

@mnivoliez
Copy link

Seems fine by me. The documentation is great, tests are explicit. Can't wait to test it out.

Should the headers be also configurable fron higher level? Like wp.setGlobalHeaders() or something?

@kadamwhite
Copy link
Collaborator Author

@mnivoliez Thanks! Regarding global headers, currently the signature is the same:

// Set for a specific request
wp.posts().whatever().methods.setHeaders({ ... });

// Set for all requests initiated from `wp`
wp.setHeaders({ ... });

I think that the repetition is preferable to introducing a new word "global"; it mirrors what we do with auth, where wp.auth() sets for all and wp[ requestFactory ]().auth() sets for one. Does that make sense?

@kadamwhite
Copy link
Collaborator Author

@gnarf thank you for the review, I always appreciate it! Regarding

there will likely be other similar configuration options you'll need to set

That's not a side of things I'd considered, I appreciate your bringing it up. However at the moment we wrap superagent, and I'm hesitant to introduce too much that would be specific to the fetch API even though it will be more broadly applicable.

At present the HTTP transport mechanism is abstracted into a module that lets the user wrap or replace some or all of the request methods, and I've deliberately limited the transport-specific methods on the query builder objects themselves. I think a switch to fetch would probably entail a broader version bump that could justify making a general-purpose config method, but I think for now we'll just introduce the method at hand.

@kadamwhite
Copy link
Collaborator Author

@mzalewski

have you considered allowing a callback as a parameter?

This is an interesting suggestion. We do not currently do that anywhere else in this library, but the pattern's pretty well established in other domains... I think I'm going to get a point release out that has the base functionality here and explore that further in a separate issue.

@kadamwhite
Copy link
Collaborator Author

Without any objection, I am going to merge this! Thanks again to y'all for raising the issue, this is a solid addition to the library's interface.

@kadamwhite kadamwhite merged commit 745c6d9 into master May 18, 2017
@kadamwhite kadamwhite deleted the feature/custom-headers branch May 18, 2017 16:24
@andreasvirkus
Copy link

andreasvirkus commented May 19, 2017

Thanks for responding (and solving the multiple issues so) quickly! 💯

@kadamwhite
Copy link
Collaborator Author

@andreasvirkus It is my pleasure. I'm resolving some docs issues and should get the 1.1 release out in the next day or two thanks to you all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Is there a way to request specific languages? i18n How to set an authorisation header?

6 participants