{"id":84,"date":"2023-11-06T00:02:21","date_gmt":"2023-11-06T00:02:21","guid":{"rendered":"https:\/\/danigarcia.org\/?p=84"},"modified":"2023-12-05T18:30:21","modified_gmt":"2023-12-05T18:30:21","slug":"bruno-an-outstanding-open-source-alternative-to-postman","status":"publish","type":"post","link":"https:\/\/danigarcia.org\/es\/2023\/11\/06\/bruno-an-outstanding-open-source-alternative-to-postman\/","title":{"rendered":"Bruno: una  genial alternativa open-source a Postman"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"585\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno000-1024x585.png\" alt=\"\" class=\"wp-image-86\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno000-1024x585.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno000-300x171.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno000-768x439.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno000-1536x878.png 1536w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno000-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno000.png 1792w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Postman has been the default tool for developing and testing APIs for years. However, unless we have the paid version, the features that the tool offers to the community for free have gradually been reduced, and the recent <a href=\"https:\/\/blog.postman.com\/announcing-new-lightweight-postman-api-client\/\">requirement to upload our environments and collections to their cloud<\/a> has made many people consider other alternative tools.<\/p>\n\n\n\n<p>Bruno is one of those alternatives that meets many of the requirements that any developer and\/or API tester asks from a tool of this type: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>It works offline (collections and environments are stored in the file system)<\/li>\n\n\n\n<li>Its interface is very way similar to Postman<\/li>\n\n\n\n<li>It offers a CLI similar to Newman<\/li>\n\n\n\n<li>Additionally, it adds a layer of extensibility that will delight any backend developer and API tester<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Installation<\/h2>\n\n\n\n<p>The installation of Bruno could not be simpler. Just go to its <a href=\"https:\/\/github.com\/usebruno\/bruno\/tags\">GitHub repository<\/a> and download the desired version. We have clients for Windows, Linux and Mac, so we can use it on any platform.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"384\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno001-1024x384.png\" alt=\"\" class=\"wp-image-85\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno001-1024x384.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno001-300x113.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno001-768x288.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno001-18x7.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno001.png 1338w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Once installed or unzipped, we will run the associated binary and we will find an interface that will be quite familiar, except for the presence of a cute little dog as the application&#8217;s pet:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno002-1024x553.png\" alt=\"\" class=\"wp-image-87\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno002-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno002-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno002-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno002-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno002.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Collections<\/h2>\n\n\n\n<p>Creating a collection is as simple as clicking on the <strong>[+ Create Collection]<\/strong> button. This will display a popup where we will fill in the following information:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Name of the collection<\/li>\n\n\n\n<li>Path where we want to store the collection (all data is stored in the filesystem)<\/li>\n\n\n\n<li>Name of the folder in which we will store the collection.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno003-1024x553.png\" alt=\"\" class=\"wp-image-88\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno003-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno003-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno003-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno003-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno003.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The fact that the collection is stored as a directory tree has other advantages, such as the possibility of creating a git repository with our team members in which to store our collections.<\/p>\n\n\n\n<p>Within our collection we can also create folders. In our collection, we click the <strong>[\u00b7\u00b7\u00b7]<\/strong> button and select the <strong>[New Folder]<\/strong> option.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"728\" height=\"441\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno004.png\" alt=\"\" class=\"wp-image-89\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno004.png 728w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno004-300x182.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno004-18x12.png 18w\" sizes=\"auto, (max-width: 728px) 100vw, 728px\" \/><\/figure>\n\n\n\n<p>Now we assign the name we want<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"839\" height=\"440\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno005.png\" alt=\"\" class=\"wp-image-90\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno005.png 839w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno005-300x157.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno005-768x403.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno005-18x9.png 18w\" sizes=\"auto, (max-width: 839px) 100vw, 839px\" \/><\/figure>\n\n\n\n<p>And with this, our folder is ready to create a request. To do this, select the folder or collection in which we want to create our request and press <strong>[\u00b7\u00b7\u00b7]<\/strong> and then, <strong>[New Request]<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"761\" height=\"454\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno006.png\" alt=\"\" class=\"wp-image-91\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno006.png 761w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno006-300x179.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno006-18x12.png 18w\" sizes=\"auto, (max-width: 761px) 100vw, 761px\" \/><\/figure>\n\n\n\n<p>Bruno allows us to make two types of requests: HTTP or GraphQL. We select the type we want, assign a name and fill in the request type and the URL where the endpoint is located. <\/p>\n\n\n\n<p>Of course, our requests can also be stored in variables, and the syntax is similar to Postman, enclosing the variables in double braces ({{variable}}):<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"965\" height=\"467\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno007.png\" alt=\"\" class=\"wp-image-92\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno007.png 965w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno007-300x145.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno007-768x372.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno007-18x9.png 18w\" sizes=\"auto, (max-width: 965px) 100vw, 965px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Environments<\/h2>\n\n\n\n<p>When creating a request, we see that the variables are highlighted in red. This is because the variables still do not exist. To do this, we will create an environment in which we will store them, and to do this we will go to the drop-down menu in the upper right corner:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno008-1024x553.png\" alt=\"\" class=\"wp-image-93\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno008-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno008-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno008-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno008-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno008.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Select the option <strong>[Configure]<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"782\" height=\"596\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno009.png\" alt=\"\" class=\"wp-image-94\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno009.png 782w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno009-300x229.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno009-768x585.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno009-16x12.png 16w\" sizes=\"auto, (max-width: 782px) 100vw, 782px\" \/><\/figure>\n\n\n\n<p>We have the option of creating a new environment or importing an existing environment. Let&#8217;s choose to create it, selecting <strong>[Create Environment]<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"506\" height=\"306\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno010.png\" alt=\"\" class=\"wp-image-95\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno010.png 506w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno010-300x181.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno010-18x12.png 18w\" sizes=\"auto, (max-width: 506px) 100vw, 506px\" \/><\/figure>\n\n\n\n<p>Assign a name to our environment:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"510\" height=\"310\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno011.png\" alt=\"\" class=\"wp-image-96\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno011.png 510w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno011-300x182.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno011-18x12.png 18w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/figure>\n\n\n\n<p>And finally, we create our variables and assign them the desired values.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno012-1024x553.png\" alt=\"\" class=\"wp-image-97\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno012-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno012-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno012-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno012-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno012.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Once this is done, the variables will appear in green color and the selected environment will be shown selected in the drop-down in the upper right corner.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"552\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno013-1024x552.png\" alt=\"\" class=\"wp-image-98\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno013-1024x552.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno013-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno013-768x414.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno013-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno013.png 1368w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Requests<\/h2>\n\n\n\n<p>The process of coding requests is very similar to the one we used in Postman: depending on the type of request we can set the parameters in the query or in the body. And by pressing the arrow <strong>[-&gt;]<\/strong> next to the request URL, we can send the request to our endpoint and get the result on the right side of the screen. As we can see, the interface is quite familiar:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno014-1024x553.png\" alt=\"\" class=\"wp-image-99\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno014-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno014-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno014-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno014-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno014.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>When sending a POST request, we can edit the request body and select its format (Multipart, URLEncoded, JSON, text, \u2026). We can also edit the headers, just as we would do with Postman.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno015-1024x553.png\" alt=\"\" class=\"wp-image-100\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno015-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno015-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno015-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno015-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno015.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Variables<\/h2>\n\n\n\n<p>As an interesting feature, Bruno allows us to <strong>assign variables before or after the request without the need to explicitly code them in a script<\/strong>. For example, let&#8217;s assume that we have an endpoint in which we access the information of a record by providing the <em>id<\/em> as part of the path, i.e.:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno016-1024x553.png\" alt=\"\" class=\"wp-image-101\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno016-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno016-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno016-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno016-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno016.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This variable is displayed in a red colour, since it has not been declared. We want its value to be the <em>id<\/em> returned by the POST request that inserts a record and returns the information stored in the database.<\/p>\n\n\n\n<p>How can we do this? Through the global variable <em>res<\/em>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Responses<\/h2>\n\n\n\n<p>The global variable <em>res <\/em>allows us to access the response in <strong>post-response scripts<\/strong>, <strong>asserts <\/strong>and <strong>tests<\/strong>. To store in a variable an element retrieved in a response, we just select the <strong>[Vars]<\/strong> tab and in the <strong>[Post response]<\/strong> section, we add in the table the name of the variable and the value it should store. In this case, we want the variable &#8220;<em>id<\/em>&#8221; to be filled with the field &#8220;<em>id<\/em>&#8221; obtained in the body of the response, so the expression that will assign value to the variable will be &#8220;<em>res.body.id<\/em>&#8220;:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno017-1024x553.png\" alt=\"\" class=\"wp-image-102\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno017-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno017-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno017-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno017-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno017.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Let&#8217;s now try executing the POST request that inserts a record. We can see that the id with which the record has been stored in the database is <em>796<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno018-1024x553.png\" alt=\"\" class=\"wp-image-103\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno018-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno018-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno018-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno018-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno018.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>If we now open again our &#8220;users&#8221; request, we can see that the <em>{{id}}<\/em> variable is now green. Moreover, if we place the mouse pointer over the variable, Bruno will show us its value, which matches the one returned in the previous request (796):<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019-1024x553.png\" alt=\"\" class=\"wp-image-104\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Authentication<\/h2>\n\n\n\n<p>Another feature offered by Bruno is the ability to configure the authentication of requests. As in Postman, it is possible to use variables to, for example, store a bearer token and use it later in the [Auth] tab to authenticate our requests.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"994\" height=\"445\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019d.png\" alt=\"\" class=\"wp-image-105\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019d.png 994w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019d-300x134.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019d-768x344.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019d-18x8.png 18w\" sizes=\"auto, (max-width: 994px) 100vw, 994px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Asserts<\/h2>\n\n\n\n<p>Another of Bruno&#8217;s features is the possibility of using assertions in the requests, so that we don&#8217;t have to code specific tests for it. <\/p>\n\n\n\n<p>Assertions are useful to perform atomic checks, such as the status of a response, the presence of a field or when we expect a specific value. The asserts are executed after obtaining the response, and to do so just open the <strong>[Assert]<\/strong> tab and fill in the table.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Expr: expression to check<\/li>\n\n\n\n<li>Operator: operator to apply to the expression<\/li>\n\n\n\n<li>Value: expected value<\/li>\n<\/ul>\n\n\n\n<p>The assertions evaluate the expression and check that, after applying the corresponding operator, the expected value is obtained.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno020-1024x553.png\" alt=\"\" class=\"wp-image-106\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno020-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno020-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno020-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno020-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno020.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Tests<\/h2>\n\n\n\n<p>If you have used Postman before, this tab will be familiar to you. In this section we will be able to code tests in Javascript, allowing us to play with the data as we were used to. However, unlike Postman, the tests are intended only for coding tests, not for post-request code. Certainly, coding those tasks in this section was something I personally didn&#8217;t like too much, as it forced the user to mix two different tasks.<\/p>\n\n\n\n<p>Therefore, if you need to perform tasks that have nothing to do with testing after the execution of a request, it is advisable to do it in its corresponding section ([Script] &gt; [Post Response]).<\/p>\n\n\n\n<p>Bruno also offers the global variable &#8220;<em>bru<\/em>&#8220;, which acts similarly to how &#8220;<em>pm<\/em>&#8221; works in Postman by offering an interface to interact with the environment. The <a href=\"https:\/\/docs.usebruno.com\/scripting\/javascript-reference.html\">tool&#8217;s documentation<\/a> provides a list of available methods and functions, such as reading and saving variables and other similar tasks.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno021-1024x553.png\" alt=\"\" class=\"wp-image-107\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno021-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno021-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno021-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno021-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno021.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Collection Runner<\/h2>\n\n\n\n<p>One of the features that Postman limited some time ago was the possibility of running complete collections or folders. Bruno allows you to do this without any restriction, and in two different flavors:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Execute a collection: executes the requests of the current folder, but not those of the subfolders.<\/li>\n\n\n\n<li>Execute a collection recursively: executes all the requests of the current folder and those of its subfolders.<\/li>\n<\/ul>\n\n\n\n<p>To make use of this feature is quite simple: just click on the <strong>[\u00b7\u00b7\u00b7]<\/strong> button of a folder and select the <strong>[Run]<\/strong> option. This will open a popup that will allow us to perform one of these two operations:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019b-1024x553.png\" alt=\"\" class=\"wp-image-108\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019b-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019b-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019b-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019b-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019b.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The result of the execution will be displayed in the &#8220;Runner&#8221; tab:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019c-1024x553.png\" alt=\"\" class=\"wp-image-109\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019c-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019c-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019c-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019c-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno019c.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Extra ball: extensibility<\/h2>\n\n\n\n<p>I leave for the end one of the features of Bruno that I have loved the most: its extensibility. <\/p>\n\n\n\n<p>Bruno allows us to use <strong>any npm package within the environment<\/strong>. Yes, <strong>ANY <\/strong>npm package. To do this, it is as simple as accessing the folder where our collection is located and initializing an npm project or creating a <em>package.json<\/em> file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"411\" height=\"197\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno022.png\" alt=\"\" class=\"wp-image-110\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno022.png 411w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno022-300x144.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno022-18x9.png 18w\" sizes=\"auto, (max-width: 411px) 100vw, 411px\" \/><\/figure>\n\n\n\n<p>Once we have our project initialized, we will install packages as if it were a node project. For example, we will install the <em>@faker-js\/faker<\/em> package to mock data in our requests:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"319\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno023.png\" alt=\"\" class=\"wp-image-111\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno023.png 627w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno023-300x153.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno023-18x9.png 18w\" sizes=\"auto, (max-width: 627px) 100vw, 627px\" \/><\/figure>\n\n\n\n<p>Finally, inside the <strong>[Script]<\/strong> tab we will import and use the packages we have imported in the normal way. In this case, the global variable &#8220;req&#8221; allows us to interact with the request before sending it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"553\" src=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno024-1024x553.png\" alt=\"\" class=\"wp-image-112\" srcset=\"https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno024-1024x553.png 1024w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno024-300x162.png 300w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno024-768x415.png 768w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno024-18x10.png 18w, https:\/\/danigarcia.org\/wp-content\/uploads\/2023\/11\/bruno024.png 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Besides that, you can edit the collection file <code>bruno.json<\/code> and add support for features like access to the filesystem or whitelist packages like <code>form-data<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">{\n  \"version\": \"1\",\n  \"name\": \"MyCollection\",\n  \"type\": \"collection\",\n  \"scripts\": {\n    \"moduleWhitelist\": [\"form-data\"],\n    \"filesystemAccess\": {\n      \"allow\": true\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>In <a href=\"https:\/\/github.com\/usebruno\/bruno\/discussions\/385\">this GitHub discussion<\/a> you can find out some tricks and howtos about how to make additional magic with this amazing tool, like uploading files or implementing an automatic OAuth2 authenticator before executing a request. It worths a try!<\/p>\n\n\n\n<p>More information:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/usebruno.com\">Bruno homepage<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/usebruno\/bruno\">Bruno git repository<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.usebruno.com\">Bruno documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/usebruno\/bruno\/discussions\/385\">Bruno Scriptmania<\/a> (recipes and code snippets for Bruno)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Postman has been the default tool for developing and testing APIs for years. However, unless we have the paid version, the features that the tool offers to the community for [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[24,20,21,23,22,25],"class_list":["post-84","post","type-post","status-publish","format-standard","hentry","category-tools","tag-alternatives","tag-api","tag-backend","tag-bruno","tag-postman","tag-tools"],"gutentor_comment":4569,"_links":{"self":[{"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/posts\/84","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/comments?post=84"}],"version-history":[{"count":4,"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/posts\/84\/revisions"}],"predecessor-version":[{"id":117,"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/posts\/84\/revisions\/117"}],"wp:attachment":[{"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/media?parent=84"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/categories?post=84"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/danigarcia.org\/es\/wp-json\/wp\/v2\/tags?post=84"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}