Bruno: Open Source API Client
Published at: 18/05/2024
Assalamualaikum!
Bruno, an inventive open-source API client, has has gained popularity in recent months. People keep talking about it since last year in Twitter, then I'd give it a try and I would say it is an amazing tool.
Bruno intended to revolutionize the status quo represented by Postman, Insomnia, and similar tools. It's goal is to offer a quick and Git-friendly API client so that developers can work together on API collections by storing them directly in a user's filesystem folder. This approach allows managing and working together on API collections using any version control system, like Git.
Features
It feels like a normal API client like Postman BUT with privacy and super power! I'll explain further down the features that I think most outstanding feature.
1. The .bru
file
With Bruno it came with .bru
extension file so we can edit API collection directly in preferred code editor. As we can see example below, there's a few format in order to create an API request to get list of addresses; meta, request, auth, assert and tests.
Meta
meta {
name: Get list of addresses
type: http
seq: 1
}
The meta format is to describe the HTTP request for a particular .bru
file. Example above, have three attributes which are:
- name: Name of the API request.
- type: Type of API request, currently only support HTTP and GraphQL.
- seq: Sequence of the
.bru
inside of a folder.
Request
get {
url: {{rest_url}}/api/addresses
body: none
auth: bearer
}
Another format is get and this is actually the HTTP method, we can change it to supported HTTP method such as post, patch or delete. This part consist of:
- url: The API url with
{{rest_url}}
is the variable we set for particular environment. - body: The body of HTTP request, for this case is none.
- auth: Authentication for this API url as selected is bearer token, currently only support AWS Sig V4, Basic Auth, Bearer Token, Digest Auth and OAuth 2.0.
If we wanna to use different HTTP method, just simply change like this:
// POST Method
post {
url: {{rest_url}}/api/addresses
body: none
auth: bearer
}
// PATCH Method
patch {
url: {{rest_url}}/api/addresses
body: none
auth: bearer
}
// DELETE Method
delete {
url: {{rest_url}}/api/addresses
body: none
auth: bearer
}
How about request body? If only need a simple input, I recommend using json
type will be good enough and we need specify the json
type body inside the request format.
post {
url: {{rest_url}}/api/addresses
body: json
auth: bearer
}
body:json {
{
"name": "Home",
"address_1": "Jalan Persiaran Junjung",
"address_2": "Taman Melati",
"postcode": "47650",
"is_primary": true
}
}
However, if file attachment is needed, that is different case. We will need to use multipart-form
type. With this, we can use @file()
provided by Bruno in which it will locate local file using given path.
post {
url: {{rest_url}}/api/addresses
body: multipart-form
auth: bearer
}
body:multipart-form {
name: Random name
logo: @file(./images.png)
}
Authentication
auth:bearer {
token: {{token}}
}
For authentication I used Bearer Token with {{token}}
variable, this token value must be set from login API. I will explain further about Asserts and Test in the next section, feel free to skip it.
2. Asserts and Tests
Bruno support automation test script in order to determine whether the response is meet expectations. For simple test, we can assertions but for complex tests, we can write test scripts. They using chai a BDD / TDD assertion library for node which similar to PestPHP for PHP, and we can have multiple test in a single .bru
file.
Assert
Example below, once the request is trigger and response will test with assert whether the HTTP code return as 200 and the data
inside response body is defined.
assert {
res.status: eq 200
res.body.data: isDefined
}
Tests
For more complex test, let say we want to verify the data
inside response body is return the correct format, we can use expect()
interface and we chain together natural language assertions. In other word, we're expect the data return to be a number or a string.
tests {
test("verify response body structure", function() {
const body = res.getBody();
let datas = body.data
for(let data of datas) {
expect(data.id).to.be.a('number');
expect(data.userId).to.be.a('number');
expect(data.name).to.be.a('string');
expect(data.address1).to.be.a('string');
expect(data.postcode).to.be.a('string');
expect(data.state).to.be.a('string');
expect(data.stateId).to.be.a('number');
expect(data.isPrimary).to.be.a('boolean');
expect(data.createdAt).to.be.a('string');
expect(data.updatedAt).to.be.a('string');
}
});
}
Result
For each test description have green tick meaning the test is passed, some goes to assertions. Otherwise, if the test or assertions are failed, then the red cross will appear.
3. Chrome Console
Can use Chrome Developer Tools to debug the request! Just simply click, three dots on left top corner and click 'Chrome Console'. It have Elements, Console, Network tab same with the Google Chrome!
We can debug the request using the Custom Script and console.log
at the Pre Request or Post Response section. Then the Console tab will appear the result.
Downside
This is just basic example of using Bruno. Of all good things, there's a few thing I need to highlight since Bruno is still new:
- Sometime it's buggy.
- Doesn't have load test feature.
- Documentation not updated.
In a nutshell.
Nevertheless, I'm not complaining much thanks to its totally offline, Git-friendly, and no-cloud-sync capabilities. Bruno has attracted a growing user base by responding to bugs and feature requests, the project demonstrates its dedication to open-source ideals and ongoing improvement, which guarantees that Bruno is developing to meet the needs of developers. Support them by subscribe the Gold Edition.
See you soon!