# 用于发起外部请求的库是什么？

**URL:** <https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147>\
**Category:** Development\
**Created:** [2019年六月12日 12:53 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147 "2019-06-12T12:53:35Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![emanuele](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/emanuele/32/142687_2.png) [@emanuele](https://meta.discourse.org/u/emanuele)\
**Post date:** [2019年六月12日 12:53 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/1 "2019-06-12T12:53:35Z")

</div>

Hello,

from a backend controller, I need to make an HTTP GET request to an external service (KeyBase) to validate user input. What’s the library the Discourse uses to do this? I tried with Faraday, but I expect a json response and `faraday_middleware` is not an available gem.

---

<div class="post-metadata">

**Author:** ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)\
**Post date:** [2019年六月12日 13:29 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/2 "2019-06-12T13:29:41Z")

</div>

Try ‘excon’ or ‘httparty’

---

<div class="post-metadata">

**Author:** ![emanuele](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/emanuele/32/142687_2.png) [@emanuele](https://meta.discourse.org/u/emanuele)\
**Post date:** [2019年六月12日 15:13 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/3 "2019-06-12T15:13:51Z")

</div>

I was able to get Faraday to work, but the tests are failing with a very strange error, it looks like Faraday is not able to make a request in the test. Is that possible? Is there something I am expected to do to be able to make external requests in tests?

EDIT: to be more clear: the request works fine in the actual page, but not in the tests.

---

<div class="post-metadata">

**Author:** ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)\
**Post date:** [2019年六月14日 07:30 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/4 "2019-06-14T07:30:23Z")

</div>

A great trick here that will save you tons of time is to look at existing specs (either for plugins or core)

The magic keyword you are looking for here is `stub_request` it is used lots of places in our spec tests, for example here:

> <https://github.com/discourse/discourse/blob/ecb2fd8222edf67b65c46362dc0b2361e3adf93a/spec/components/file_helper_spec.rb#L36-L48>

We use [GitHub - bblimke/webmock: Library for stubbing and setting expectations on HTTP requests in Ruby. · GitHub](https://github.com/bblimke/webmock) so pretty much anything should work, if you simply need a simple HTTP get, this class has simple example of how we use FinalDestination class that wraps stuff for you.

> <https://github.com/discourse/discourse/blob/ecb2fd8222edf67b65c46362dc0b2361e3adf93a/lib/file_helper.rb#L39-L47>

For a simple get excon may be overkill. We have been slowly winding down on our excon use in core due to strangeness with it. I would recommend avoiding faraday we don’t ever use it in core.

Regarding getting stuck with specs. A huge time saver is

```plaintext
bin/rake autospec

```

Once you run that, save you `plugin.rb` file and right away all the specs will run, same goes for specific controller specs.

---

<div class="post-metadata">

**Author:** ![emanuele](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/emanuele/32/142687_2.png) [@emanuele](https://meta.discourse.org/u/emanuele)\
**Post date:** [2019年六月14日 07:36 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/5 "2019-06-14T07:36:44Z")

</div>

Thank you 🙂 my struggle with this specific issue was that I couldn’t find a spec to learn from 😃 I found `stub_request` and tried to use it, but I think I got into one of the strange issues with Faraday you mentioned because the spec kept failing 😃

One question: so I should keep `bin/rake autospec` running while I am working on the plug-in and it will automatically pick the changes and run the tests again?

Thanks for unblocking me 🙂

---

<div class="post-metadata">

**Author:** ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)\
**Post date:** [2019年六月14日 07:38 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/6 "2019-06-14T07:38:58Z")

</div>

> [@emanuele](#):
>
> One question: so I should keep `bin/rake autospec` running while I am working on the plug-in and it will automatically pick the changes and run the tests again?

Yes, there is also a fantastic trick I use I highly recommend.

Say I am working on `something_spec.rb` in the plugin I will edit in:

```plaintext
it "I am working on this spec" do
   boom
end

```

Then I save it … and I am well focused on the broken specs. Then I improve the spec, leaving the “boom” at the end so autospec stays focused, saving other files and the spec file as I go. autospec stays focused and keeps running as needed.

---

<div class="post-metadata">

**Author:** ![emanuele](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/emanuele/32/142687_2.png) [@emanuele](https://meta.discourse.org/u/emanuele)\
**Post date:** [2019年六月18日 15:59 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/7 "2019-06-18T15:59:03Z")

</div>

> [@sam](#):
>
> Then I save it … and I am well focused on the broken specs. Then I improve the spec, leaving the “boom” at the end so autospec stays focused, saving other files and the spec file as I go. autospec stays focused and keeps running as needed.

It looks like `bin/rake autospec` is not checking plugin tests for me. If I use `LOAD_PLUGINS=1 bin/rake autospec`, then a ton of tests start failing (probably the ones related to other plugins).

I tried running `bin/rake db:migrate` to create the tables that the plugins need, but to no avail. Many tests keep failing…

EDIT: Ok, here’s the trick:

```plaintext
RAILS_ENV=test bin/rake db:migrate
LOAD_PLUGINS=1 bin/rake autospec

```

Running `autospec` right now, it should work as expected after the first run…

---

<div class="post-metadata">

**Author:** ![emanuele](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/emanuele/32/142687_2.png) [@emanuele](https://meta.discourse.org/u/emanuele)\
**Post date:** [2019年六月18日 17:52 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/9 "2019-06-18T17:52:36Z")

</div>

(Tagging @sam 😃)

So, I am running `LOAD_PLUGINS=1 bin/rake autospec`, but other specs fail, so my spec file is never picked. Is it normal that the first time it runs it takes more than 10 minutes?

This is the output:

```plaintext
Failures:

  1) UsersController#perform_account_activation valid token welcome message enqueues a welcome message if the user object indicates so
     Failure/Error: expect(Jobs::SendSystemMessage.jobs.size).to eq(1)

       expected: 1
            got: 0

       (compared using ==)
     # ./spec/requests/users_controller_spec.rb:34:in `block (5 levels) in <main>'

  2) User.enqueue_welcome_message enqueues the system message
     Failure/Error: Jobs.expects(:enqueue).with(:send_system_message, user_id: user.id, message_type: 'welcome_user')

     Mocha::ExpectationError:
       not all expectations were satisfied
       unsatisfied expectations:
       - expected exactly once, not yet invoked: Jobs.enqueue(:send_system_message, {:user_id => 3883, :message_type => "welcome_user"})
     # ./spec/models/user_spec.rb:152:in `block (3 levels) in <main>'

```

In total, 8 specs are failing (in addition to mine)…

EDIT: an update. `bin/rake autospec` (without `LOAD_PLUGINS=1`) fails too, with 4 failures instead of 8.

---

<div class="post-metadata">

**Author:** ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)\
**Post date:** [2019年六月19日 00:59 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/10 "2019-06-19T00:59:58Z")

</div>

> [@emanuele](#):
>
> `bin/rake autospec`

You should not need to add `LOAD_PLUGINS=1` we handle this automatically here:

> <https://github.com/discourse/discourse/blob/03ba1d49fbdceaeec76301b0811daba5dca6cb94/lib/autospec/simple_runner.rb#L38-L41>

All you need to do is save a spec file (or plugin.rb) in your plugin directory.

Maybe somehow your test db is off?

Try creating it from scratch:

```plaintext
RAILS_ENV=test bin/rake db:drop
RAILS_ENV=test bin/rake db:create
RAILS_ENV=test bin/rake db:migrate

```

---

<div class="post-metadata">

**Author:** ![emanuele](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/emanuele/32/142687_2.png) [@emanuele](https://meta.discourse.org/u/emanuele)\
**Post date:** [2019年六月19日 01:33 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/11 "2019-06-19T01:33:07Z")

</div>

I had already tried to recreate the database several times, to no avail.

Maybe the problem is that I am symlinking my plugin directory inside `plugins/`? But this is what the plugins guide tells me to do so I doubt…

Anyway, the _only_ command that works for me so far to run tests is: `bin/rake 'plugin:spec[keybase-proofs]'`

Everything else fails ☹

---

<div class="post-metadata">

**Author:** ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)\
**Post date:** [2019年六月19日 08:58 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/12 "2019-06-19T08:58:02Z")

</div>

@daniel something here sounds off, can you help debug? The repo @emanuele is using is on GitHub

---

<div class="post-metadata">

**Author:** ![emanuele](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/emanuele/32/142687_2.png) [@emanuele](https://meta.discourse.org/u/emanuele)\
**Post date:** [2019年六月24日 10:24 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/13 "2019-06-24T10:24:37Z")

</div>

@sam, @daniel, it turns out that `autospec` doesn’t work with symlinked directories in `plugins/`, so I just checked out my repo directly in `plugins/` instead of symlinking it.

Now it looks like it works fine 🙂 🥳

---

<div class="post-metadata">

**Author:** ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)\
**Post date:** [2019年六月24日 10:36 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/14 "2019-06-24T10:36:13Z")

</div>

I fixed something around symilinks a while back, can you have a look at the code? Maybe my fix is Linux only?

---

<div class="post-metadata">

**Author:** ![emanuele](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/emanuele/32/142687_2.png) [@emanuele](https://meta.discourse.org/u/emanuele)\
**Post date:** [2019年六月24日 10:51 UTC](https://meta.discourse.org/t/what-is-the-library-used-to-make-external-requests/120147/15 "2019-06-24T10:51:05Z")

</div>

Sure, I’ll give it a look 🙂

> [@sam](#):
>
> Maybe my fix is Linux only?

I remember that the FS watching abstractions that macOS uses are quite different from the Linux ones, so I wouldn’t be surprised if that was the case.
