2 releases (1 stable)
1.0.0 | Jul 27, 2023 |
---|---|
0.1.0 | Jun 30, 2023 |
#9 in #body
62KB
1.5K
SLoC
apictl
apictl
is a command-line application for interacting with APIs. See
the documentation below or run apictl help
for details.
Installation
Binaries are available via releases.
You can also install it using cargo:
cargo install apictl
Getting Started
Example
This repository includes an example .apictl.yaml
file. It interacts with Typicode's
json-server
. You can
install it via npm and then run it in some other shell:
npm install -g json-server
json-server http://jsonplaceholder.typicode.com/db
You should now be able to clone this repository run the examples within it:
git clone https://github.com/icub3d/apictl
cd apictl
apictl requests list
apictl requests run -c local get-posts get-user-from-first-post
apictl requests run -c local new-post get-new-post
From Scratch
If you have an existing API you'd like to use, start by creating a configuration for it. It is common for the configuration to be in the repository in which the API is created.
Next, create contexts for the various environments that you'll be using.
Then create requests for any API calls you are interested in running.
Finally, do, some testing on your configuration before publishing your code.
Configuration
You can look at .apictl.yaml for an example
configuration. Configurations are defined using
YAML. By default, apictl
will look for a file
named .apictl.yaml
in the current directory.
If your project is large enough, you can use a folder to store
multiple configuration files. To do this, run apictl
with the flag
--config CONFIG
where CONFIG is the path to your folder. Folder are
read in sorted order and configuration are merged. When information
overlaps (e.g. two requests with the same name) the later overwrites
the former.
Details on values within the configuration can be found below.
Contexts
Contexts are ways to define variables for your API calls. Within your
configurations, they are created under the contexts
key. Each
context is a map that contains the variables and the values to
replace. For example, suppose you want to differentiate the URL to use
in requests for your local, dev, staging, and prod environments. You
might do it like this:
contexts:
local:
base_url: http://localhost:3000
dev:
base_url: https://dev.app
staging:
base_url: https://staging.app
prod:
base_url: https://my-cool-api.com
You can now use the variable base_url
in your requests and it will
be replaced with the value based on the context given. If you want to
run a request using dev, you'd add a flag --context dev
.
Currently, all variables within the request are replaced if they are strings. If the body contains strings, they are replaced. File references will have their path replaced but not the actual content.
Variables
Once you have your contexts defined, you can using them in your
configuration using the pattern ${name}
where name is the key in the
context.
Multiple Contexts
You can use multiple contexts which are merged in a similar fashion to configurations. This may be useful when you have multiple interactions that may not overlap. For example, you might have multiple authentication mechanisms you'd like to test for the same API. You can use a context for the environment and then for the authentication method.
To use multiple contexts, simply add multiple context flags to your
command: --context basic-auth --context local
.
Requests
Requests are API endpoints and the information necessary to make the
requests. They are They also contain basic information like tags
and
descriptions
that can be used for searching for requests.
Within your configurations, they are created under the requests
key. They contain configuration for including the request method, url,
query parameters, headers, and the body. All but the body is
self-explanatory. Here is an example request:
requests:
get-posts:
tags: [get]
description: a simple get
url: "${base_url}/posts"
query_parameters:
_limit: "${pagination_limit}"
Body
The request body can come in several forms. This section describes
each of them in detail and how to use them. Each body type is
described by the type
field.
Form
If you just want to submit key/value pairs, You can use the "form"
type
and it will POST a application/x-www-form-urlencoded
. An example of this:
requests:
new-post:
tags: [post]
description: an example post using the form type
url: "${base_url}/posts"
method: POST
body:
type: form
data:
name: World
age: 4.543 billion years
Multi-part Form
If you have files you want to send, you'll probably want to use the
multipart format. It works similar to the From but allows you to
specify each field's type, You use the "multipart" type
and it will
POST a multi-part message. An example of this:
requests:
new-post:
tags: [post]
description: an example post using the multipart type
url: "${base_url}/posts"
method: POST
body:
type: multipart
data:
name:
type: text
data: World
age:
type: text
data: 4.543 billion years
avatar:
type: file
path: ./avatar.png
The "file" type
will expect a file at the given path
and put it's
contents in the form submission.
Raw
If you just want to submit a raw body, use the "raw" type
. The data
can come from text or a file and will send the contents as the
body. An example of using text:
requests:
new-post:
tags: [post]
description: an example post using the raw type
url: "${base_url}/posts"
method: POST
body:
type: raw
from:
type: text
data: |
{
"userId": 1,
"title": "test post",
"body": "This is a test post to the json server."
}
And an example of using a file:
requests:
new-post:
tags: [post]
description: an example post using the raw type
url: "${base_url}/posts"
method: POST
body:
type: raw
from:
type: file
path: ./new-post-body.json
Dependencies
~16–29MB
~448K SLoC