GithubHelp home page GithubHelp logo

httpie's Introduction

httpie
A Node.js HTTP client as easy as pie!

Features

  • Promise- based HTTP requestor
  • Works with HTTP and HTTPS protocols
  • Automatically handles JSON requests and responses
  • Extremely lightweight with no dependencies 678 bytes!
  • Includes aliases for common HTTP verbs: get, post, put, patch, and del

Additionally, this module is delivered as:

Install

$ npm install --save httpie

Usage

Note: The async syntax is for demo purposes โ€“ you may use Promises in a Node 6.x environment too!

import { get, post } from 'httpie';

try {
  const { data } = await get('https://pokeapi.co/api/v2/pokemon/1');

  // Demo: Endpoint will echo what we've sent
  const res = await post('https://jsonplaceholder.typicode.com/posts', {
    body: {
      id: data.id,
      name: data.name,
      number: data.order,
      moves: data.moves.slice(0, 6)
    }
  });

  console.log(res.statusCode); //=> 201
  console.log(res.data); //=> { id: 1, name: 'bulbasaur', number: 1, moves: [{...}, {...}] }
} catch (err) {
  console.error('Error!', err.statusCode, err.message);
  console.error('~> headers:', err.headers);
  console.error('~> data:', err.data);
}

API

send(method, url, opts={})

Returns: Promise

Any httpie.send request (and its aliases) will always return a Promise.

If the response's statusCode is 400 or above, this Promise will reject with a formatted error โ€“ย see Error Handling. Otherwise, the Promise will resolve with the full ClientRequest stream.

The resolved response will receive a new data key, which will contain the response's full payload. Should the response return JSON content, then httpie will parse it and the res.data value will be the resulting JSON object!

method

Type: String

The HTTP method name โ€“ it must be uppercase!

url

Type: String or URL

If url is a string, it is automatically parsed with url.parse() into an object.

opts.body

Type: Mixed
Default: undefined

The request's body, can be of any type!

Any non-Buffer objects will be converted into a JSON string and the appropriate Content-Type header will be attached.

Additionally, httpie will always set a value for the Content-Length header!

opts.headers

Type: Object
Default: {}

The custom headers to send with your request.

opts.redirect

Type: Boolean
Default: true

Whether or not redirect responses should be followed automatically.

Note: This may only happen with a 3xx status and if the response had a Location header.

opts.reviver

Type: Function
Default: undefined

An optional function that's passed directly to JSON.parse, allowing you transform aspects of the response data before the httpie request resolves.

Note: This will only run if httpie detects that JSON is contained in the response!

get(url, opts={})

Alias for send('GET', url, opts).

post(url, opts={})

Alias for send('POST', url, opts).

put(url, opts={})

Alias for send('PUT', url, opts).

patch(url, opts={})

Alias for send('PATCH', url, opts).

del(url, opts={})

Alias for send('DELETE', url, opts).

Error Handling

All responses with statusCode >= 400 will result in a rejected httpie request. When this occurs, an Error instance is formatted with complete information:

  • err.message โ€“ String โ€“ Identical to err.statusMessage;
  • err.statusMessage โ€“ String โ€“ The response's statusMessage value;
  • err.statusCode โ€“ Number โ€“ The response's statusCode value;
  • err.headers โ€“ Object โ€“ The response's headers object;
  • err.data โ€“ Mixed โ€“ The response's payload;

Important: The error's data property may also be parsed to a JSON object, according to the response's headers.

import { get } from 'httpie';

get('https://example.com/404').catch(err => {
  console.error(`(${err.statusCode}) ${err.message}`)
  console.error(err.headers['content-type']);
  console.error(`~> ${err.data}`);
});
//=> "(404) Not Found"
//=> "text/html; charset=UTF-8"
//=> ~> <?xml version="1.0" encoding="iso-8859-1"?>\n<!DOCTYPE html ...</body>\n</html>

License

MIT ยฉ Luke Edwards

httpie's People

Contributors

charlyx avatar forsakenharmony avatar lukeed avatar roblav96 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

httpie's Issues

ESM module for both Node.js and the Browser?

Hi @lukeed, it's me again! How're you doing? ๐Ÿ˜„

(Thanks for the help you gave here a few months ago ๐Ÿฅณ colyseus/colyseus.js#64 (comment))

Continuing that discussion - I see you're using the same pattern for every project of yours - but they don't seem to work nicely with vite / snowpack / webpack (v5) - I've created a repository reproducing it here: https://github.com/endel/esm-browser-node

ESM modules seem to be finally rolling out with modern frontend tooling, and it seems we can't have a "browser" field, or anything like it. That makes it difficult for us maintainers to keep a module compatible with as many environments as possible. This seems to be a problem in the ecosystem.

I also created the same issue here trying to get some answers: vitejs/vite#1154

Thanks for your support! ๐Ÿ™

Caching support

Hello, I have a question regarding caching. Is it supported, e.g. saving stuff to files not to make new requests?

Atm I'm using node-fetch-cache but would like to switch to httpie

How to Timeout requests

Hey there!

How do I timeout requests?

I can't get this to work:

const httpsResp = await get(httpsUrl, { timeout: 2000 })

It looks like #17 wasn't merged in.

Follow Redirects?

This would be fairly straightforward & could totally be fit in as a minor bump.

Any 3xx response (that also has a location header) should automatically be followed. Of course, httpie will appropriately handle relative, absolute, and complete location values.

The questions are:

  1. Should httpie handle redirects?
    I assume the majority will vote yes, because why not?


  1. Should httpie do this automatically, or put it behind a opts flag?
    Again, I'd assume majority yes because why would you not want to follow it?



Could not find a declaration file for module 'httpie'

Hi, I've installed your library but some weird TypeScript error appeared.
typescript: 5.2.2
httpie: ^2.0.0-next.13

Could not find a declaration file for module 'httpie'. 'e:/repos/tft-roller/tft-roller-client/node_modules/httpie/node/index.mjs' implicitly has an 'any' type.
  There are types at 'e:/repos/tft-roller/tft-roller-client/node_modules/httpie/index.d.ts', but this result could not be resolved when respecting package.json "exports". The 'httpie' library may need to update its package.json or typings.ts(7016)

Screenshot 2024-01-23 231644

Send form-data

Hi ๐Ÿ‘‹
I want to send a form-data request with httpie and I haven't found how.
Axios and Got, use the form-data library. I haven't tried it yet in httpie, but is this the way to go here?

By the way, my attempt was like this

const res = await post('https://api.instagram.com/oauth/access_token', {
        body: {
          client_id: process.env.APP_ID,
          client_secret: process.env.APP_SECRET,
          grant_type: 'authorization_code',
          redirect_uri: process.env.REDIRECT_URI,
          code: req.query.code
        },
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      })

ERR_PACKAGE_PATH_NOT_EXPORTED

Hi,

I'm switching to the next version to be able to use the timeout option but doesn't seem to work. I'm using it with CJS by the way.

Pkg version: ^2.0.0-next.8
Node version: 14.2.0

internal/modules/cjs/loader.js:491
  throw new ERR_PACKAGE_PATH_NOT_EXPORTED(basePath, mappingKey);
  ^

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main resolved in F:\Code\SlimIO\Npm-registry\node_modules\httpie\package.json
    at applyExports (internal/modules/cjs/loader.js:491:9)
    at resolveExports (internal/modules/cjs/loader.js:507:23)
    at Function.Module._findPath (internal/modules/cjs/loader.js:635:31)
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1007:27)
    at Function.Module._load (internal/modules/cjs/loader.js:890:27)
    at Module.require (internal/modules/cjs/loader.js:1080:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (F:\Code\SlimIO\Npm-registry\index.js:5:17)
    at Module._compile (internal/modules/cjs/loader.js:1176:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1196:10) {
  code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}

I guess there something wrong with the CJS Export ? I have not updated my code so i require like this

const { get } = require("httpie");

Best Regards,
Thomas

npm "readme" is totally blank

Been using httpie for a while, and just noticed today that on npm the whole readme section is blank:
image

I believe this is because npm expects capitalized README.md and you've got lower cased readme.md.

Trying to search on npm for httpie without actually using httpie (e.g. "lightweight http" etc.) doesn't show any results, so I'd wager that their search index uses the README.md content.

Not a critical issue of course, just thought I'd drop you a note.

Expose RAW Response object

NOTE: not really an issue

i want to preform the following using httpie

const file = fs.createWriteStream("file.jpg");
const request = http.get("https://somedomain.com/sampleimage.jpg", function(response) {
  response.pipe(file);
});

whats the best way of doing so?

double note: im asking here as it might be a good example to have for other users

[next] exports field browser conditional ordering

Ran into this when a user is trying to use httpie@next with Vite 2.

Currently the exports field has the following conditionals:

  "exports": {
    ".": {
      "import": "./node/index.mjs",
      "require": "./node/index.js",
      "browser": "./xhr/index.mjs",
      "worker": "./fetch/index.mjs"
    }
  }

From the bundler's perspective, it will resolve the import conditional immediately because that matches the ESM environment. However, the file actually points to the node version.

According to the docs:

The general rule is that conditions should be from most specific to least specific in object order.

So in this case, browser should be listed before import in order for browser-targeting bundlers to prioritize it. It is ok to list it first because Node.js will ignore it. worker should probably be listed before import and require as well.

Headers are not being send

After bashing my head for something simple not working I found out httpie does not send the headers passed in the options. I don't want to be rude but reading the code to find this out was pretty hard with all the single letter variables.

Browser Version

Disclaimer: The browser implementation is already done! I'm just deciding if it should be a part of httpie or be its own thing.

Should httpie offer a browser implementation? I've received the request a few times already & have also seen some people try to use httpie in the browser.

Unfortunately, if you do try to do that right now, it technically will work in a webpack setting, but it will only be because webpack injected multiple kBs worth of shims & polyfills ๐Ÿ˜ฑ That kinda defeats the point & needs fixing IMO.

So โ€“ again, should httpie offer a browser implementation of itself? The API would be the same1 and would operate a lot like axios, meaning that browser builds get the browser copy, and node builds get the Node.js version of axios โ€“ all without changes needed from the dev.

1 some options will need to be different across versions

Details:

Most libraries will do a "runtime check" and load a version on the condition of something like process being defined or not. This poses two major problems:

  1. This is not tree-shakeable
  2. Tools like webpack automatically shim Node globals like process with weak/empty objects. Because of this, the library's typeof process === 'undefined' ? BROWSER : NODE will not behave as expected.

To get around this, we'd have to make use of package.json entry fields. While not a perfect system, most (all?) build tools have agreed on some standard keys, allowing `httpie to do the following:

  • "main" โ€“ (Node) CommonJS format
  • "module" โ€“ (Node) ESModule format
  • "browser" โ€“ (Browser) ESModule2 format
  • "unpkg" โ€“ (Browser) UMD format

2 Now, as far as I can tell, there's no rule nor standard as to what format the "browser" entry should be. Typically (and historically) this has been CommonJS format because that's all JavaScript had. However, with the advent of ESM, webpack and Rollup actually accept ESM files through that entry point. I anticipated that only "module" fields "unlocked" ESM parsing, but this was happily NOT the case! ๐ŸŽ‰

The above allows Node and Browser environments to grab the appropriate files, with the added benefit of kicking off an unpkg.com access.

I've verified that the 4 entries resolve successfully in default and/or the most basic Rollup and webpack configurations. Absolutely nothing special was needed to make this happen!

PROs

  • No accidental/broken browser usage
  • No webpack shims & polyfills
  • No extra client-side library for HTTP requests
  • Same HTTP library API for clients & servers
  • Browser version will be under 500 bytes
  • Browser-httpie becomes accessible via unpkg.com

CONs

  • Some httpie options will need to be different in Node vs Browser
  • Some httpie options will only work in Node and/or Browser
  • Browser builds will require unpkg.com link or FE tooling (Webpack, Rollup)

Please leave thoughts/comments below โ€“ I'd like to make this happen ASAP one way or another.

Thanks! ๐Ÿ‘‹

Inconsistent response handling in v2

Consider a request to a server that successfully returns XML data (aka anything that is not JSON).

In the node version we have this flow:

  1. construct out as the concatenated data stream string
  2. since the header content-type does not include application/json so...
  3. the response data property is set to the out (aka the response body realized)
  4. the promise is resolved with that response (aka response.data is the response body XML string)

However, in the fetch version we have this flow:

  1. the header content-type does not include application/json so...
  2. try to parse the string from fetch.text() as JSON
  3. since the response is XML this throws
  4. set the error on the response
  5. the promise is rejected but the fetch.text() string is not available on the response

Should not reject on 400+ responses

Great work on this module. One recommendation is that you should not reject on 400+ responses. From discussions throughout other like projects (whatwg/fetch#18) I believe its a common practice to allow the user to decide what happens with their response. The promise should only reject if an actual network error occurs.

Now, this is your library and 100% your opinion so I'm not telling you to change anything; just sharing information you may not have been exposed to.

Good work nonetheless!

Use of send.bind(send, 'METHOD') prevents tree shaking with Rollup

I'm working with the next v2 branch! This is so minor because it's like... four lines. ๐Ÿ˜…

I'm working on a library that bundles in httpie instead of importing it (because it's so small, so why not? ๐Ÿ™Œ ) and I noticed that even though I was only importing post the other four helpers were also there. I guess Rollup is being extra careful with bind and includes them in case of any side effects?

When I converted it to something like this (not necessarily recommending it):

export const get = (...args) => send('GET', ...args);
export const post = (...args) => send('POST', ...args);
export const patch = (...args) => send('PATCH', ...args);
export const del = (...args) => send('DELETE', ...args);
export const put = (...args) => send('PUT', ...args);

Then it'd tree shake just fine.

Nameclash

Hello

https://httpie.org/ is python http library and cli client.
I think you better change name, because it will create troubles for googling your/theirs library

next "timeout" doesn't work as expected (i guess)

Hi,

Recently in one of my project Node-secure i spotted that the part of the code that was responsible to fetch data on the npm registry was not able to properly terminate (some asynchronous function never end).

This code use one of my package that is: https://github.com/SlimIO/Npm-registry. I recently updated this package with the next version of httpie in hope to fix the problem with the new timeout option.

But the problem is still there :\

I made a repository to reproduce the problem without all the noise: https://github.com/fraxken/httpie_timeout_bug

Sometimes it work (i guess it work when npm return 200 for every packages of the list). But sometimes it seem to never end (even with the timeout).

Best Regards,
Thomas

withCredentials

Hi Luke,
how's to set withCredentials with httpie@next?

Thanks

WHATWG URL not working

Hi,

The Type definition for your method take string | Url but you seem to have forgotten to transform the URL to a standard string. If we send an URL, it throw the following error:

TypeError: Cannot read property 'startsWith' of undefined
    at urlToOptions (internal/url.js:1260:28)
    at request (https.js:293:15)
    at Promise (F:\Code\orders\node_modules\httpie\dist\httpie.js:13:13)
    at new Promise (<anonymous>)
    at send (F:\Code\orders\node_modules\httpie\dist\httpie.js:6:9)
    at test (F:\Code\orders\test\test.js:48:19)
    at asPromise (F:\Code\orders\node_modules\japa\build\src\Callable\index.js:7:18)
    at Callable.Promise (F:\Code\orders\node_modules\japa\build\src\Callable\index.js:64:9)
    at new Promise (<anonymous>)
    at Object.Callable (F:\Code\orders\node_modules\japa\build\src\Callable\index.js:10:12)

Best Regards,
Thomas

Custom JSON reviver

What do you think about letting the user determine a custom JSON reviver? Would be pretty useful for reviving Date objects.

V2 Release Date

Hi! I see we're working hard on version two. When should we expect it?)

Cannot find module 'url'

Hi,

When I add httpie to an angular project I get the following error:

Error: node_modules/httpie/index.d.ts:1:21 - error TS2307: Cannot find module 'url' or its corresponding type declarations.

1 import { Url } from 'url'; 

As a workaround, I just removed the 'import' statement and the 'Url' references and it seems to work fine.

export function send<T = any>(method: string, uri: string | URL, opts?: Partial<Options>): Promise<Response<T>>;

declare function method<T = any>(uri: string | URL, opts?: Partial<Options>): Promise<Response<T>>;

If it really doesn't break anything, maybe this patch can be pushed to the repository.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.