Building APIs in Laravel

https://laravelnews.s3.amazonaws.com/images/building-apis-in-laravel.png

Building APIs in Laravel is an art form. You must think beyond data access and wrapping your Eloquent Models in API endpoints.

The first thing you need to do is design your API; the best way to do this is to think about the purpose of your API. Why are you building this API, and what is the target use case? Once you have figured this out, you can effectively design your API based on how it should be integrated.

By focusing your perspective on how your API should be integrated, you can eliminate any potential pain points within your API before it is even released. This is why I always test integrating any APIs I build to ensure a smooth integration that covers all use cases I intend to have.

Let’s talk through an example to paint a picture. I am building a new bank, Laracoin. I need my users to be able to create accounts and create transactions for these accounts. I have an Account model, a Transaction model, and a Vendor model to which each transaction will belong. An example of this is:

Account -> Has Many -> Transaction -> Belongs To -> Vendor

 

Spending Account -> Lunch 11.50 -> Some Restaurant

So we have three main models that we need to focus on for our API. If we were to approach this without any design-led thinking, then we would create the following routes:

GET /accounts

POST /accounts

GET /accounts/{account}

PUT|PATCH /accounts/{account}

DELETE /accounts/{account}

 

GET /transactions

POST /transactions

GET /transactions/{transaction}

PUT|PATCH /transactions/{transaction}

DELETE /transactions/{transaction}

 

GET /vendors

POST /vendors

GET /vendors/{vendor}

PUT|PATCH /vendors/{vendor}

DELETE /vendors/{vendor}

However, what are the benefits of these routes? We are just creating JSON access for our eloquent models, which works – but adds zero value, and from an integration perspective, it makes things feel very robotic.

Instead, let’s think about the Design and Purpose of our API. Our API will likely be accessed by mostly internal mobile and web applications. We will focus on these use cases to start with. Knowing this means we can fine-tune our API to fit the user journeys in our applications. So typically, in these applications, we will see a list of accounts, as we can manage our accounts. We will also have to click through to an account to see a list of transactions. We will then have to click on a transaction to see more details. We would never really need to see the vendors directly, as they are there more for categorization than anything else. With that in mind, we can design our API around these use cases and principles:

GET /accounts

POST /accounts

GET /accounts/{account}

PUT|PATCH /accounts/{account}

DELETE /accounts/{account}

 

GET /accounts/{account}/transactions

GET /accounts/{account}/transactions/{transaction}

 

POST /transactions

This will allow us to manage our accounts effectively and only be able to fetch transactions directly through the account to which it belongs. We do not want transactions to be edited or managed now. These should be created only – and from there, an internal process should update these should they be required.

Now that we know how our API is meant to be designed, we can focus on how to build this API to ensure it responds quickly and can scale in terms of its complexity.

Firstly, we will make the assumption that we are building an API-only Laravel application – so we will not need any api prefix. Let’s think about how we might register these routes, as this is often the first part of your application that sees problems. A busy routes file is hard to parse mentally, and the cognitive load is the first battle in any application.

If this API were going to be public facing, I would look into supporting a versioned API, in which case I would create a version directory and keep each main group in a dedicated file. However, we aren’t using versioning in this case so we will organize them differently.

The first routes file we want to create is routes/api/accounts.php, which we can add to our routes/api.php.

Route::prefix('accounts')->as('accounts:')->middleware(['auth:sanctum', 'verified'])->group(

base_path('routes/api/accounts.php),

);

Each group will load in its routes, setting up the default middleware prefix and route naming pattern. Our route file for accounts will be flat with minimal grouping other than when we want to look at sub-resources. This allows us to have only one area to look at when trying to understand the routes themselves, but it means that anything and everything to do with accounts will belong in this file.

Route::get(

'/',

App\Http\Controllers\Accounts\IndexController::class,

)->name('index');

Our first route is the accounts index route, which will show all accounts for the authenticated user. This is likely the first thing called through the API aside from the authentication routes, so it is where I typically focus first. It is essential to look at the most critical routes first to unblock other teams, but also it allows you to flesh out the standards you want to follow within your application.

Now that we understand how we are routing our requests, we can think about how we want to process these requests. Where does the logic live, and how can we ensure we keep code duplication to a minimal amount?

I recently wrote a tutorial about how to use Eloquent Effectively, which dives into query classes. This is my preferred approach, as it ensures that we have a minimal amount of code duplication. I won’t go into the specifics as to why I will use this approach, as I went into detail in the previous tutorial. However, I will walk through how to use it in your application. You can follow this approach if it suits your needs.

The critical thing to remember is that the best way to get the most out of your API is to build it in a way that works for you and your team. Spending hours trying to adjust to a method that doesn’t feel natural will only slow you down in a way that won’t give you the benefit you are trying to achieve.

When creating a query class, you need to make the corresponding interface bind to the controller. This isn’t a required step. However, it is me writing the tutorial – so what did you expect, really?

interface FilterForUserContract

{

public function handle(Builder $query, string $user): Builder;

}

Then the implementation we want to use:

final class FilterAccountsForUser implements FilterForUserContract

{

public function handle(Builder $query, string $user): Builder

{

return QueryBuilder::for(

subject: $query,

)->allowedIncludes(

include: ['transactions'],

)->where('user_id', $user)->getEloquentBuilder();

}

}

This query class will get all accounts for the passed-through user, allowing you to include the transactions for each account optionally – then pass back the eloquent builder to add additional scopes where needed.

We can then use this within our controller to query the accounts for the authenticated user, then return them within our response. Let’s look at how we might use this query to understand the available options.

final class IndexController

{

public function __construct(

private readonly Authenticatable $user,

private readonly FilterForUserContract $query,

) {}

 

public function __invoke(Request $request): Responsable

{

$accounts = $this->query->handle(

query: Account::query()->latest(),

user: $this->user->getAuthIdentifier(),

);

 

// return response here.

}

}

At this point, our controller has an eloquent builder that will pass to the response, so when passing the data, make sure you either call get or paginate to pass the data through properly. This leads us to the next point in my opinionated journey.

Responding is the primary responsibility of our API. We should respond quickly and efficiently to have a fast and responsive API for our users to experience. How we respond as an API can be split into two areas, the response class and how the data is transformed for the response.

These two areas are Responses and API Resources. I will start with the API Resources, as I care very much about them. API Resources are used to obfuscate away from the database structure and a way for you to transform the information stored in your API in a way that will best be consumed on the client side.

I use JSON:API standards within my Laravel APIs as it is an excellent standard that is well-documented and used within the API community. Luckily Tim MacDonald has created a fantastic package for creating JSON:API resources in Laravel, which I swear by in all of my Laravel applications. I have recently written a tutorial on how to use this package, so I will only go into some detail here.

Let us start with the Account Resource, which will be set up to have the relevant relationships and attributes. Since my last tutorial, the package has been updated recently, making setting relationships up easier.

final class AccountResource extends JsonApiResource

{

public $relationships = [

'transactions' => TransactionResource::class,

];

 

public function toAttributes(Request $request): array

{

return [

'name' => $this->name,

'balance' => $this->balance->getAmount(),

];

}

}

We are keeping this super simple for now. We want to return the account name and balance, with an option to load in the transactions relationship.

Using these resources means that to access the name, and we would have to use: data.attributes.name, which may take a while to get used to in your web or mobile applications, but you will get the hang of it soon enough. I like this approach, as we can separate the relationships and attributes and extend them where needed.

Once our resources are filled out, we can focus on other areas, such as Authorization. This is a vital part of our API and should not be overlooked. Most of us have used Laravels Gate before, using the Gate Facade. However, I like injecting the Gate contract from the framework itself. This is mainly because I prefer Dependency Injection over Facades when I get a chance. Let’s look at what this might look like in the StoreController for accounts.

final class StoreController

{

public function __construct(

private readonly Gate $access,

) {}

 

public function __invoke(StoreRequest $request): Responsable

{

if (! $this->access->allows('store')) {

// respond with an error.

}

 

// the rest of the controller goes here.

}

}

Here we are just using the Gate functionality as if it were the facade, as they are the same thing. I use allows here, but you can use can or other methods. You should focus on Authorization over how it is implemented, as this is a minor detail for your application at the end of the day.

So we know how we want the data to be represented in the API and how we want to authorize users in the application. Next, we can look at how we might handle write operations.

When it comes to our API, write operations are vital. We need to ensure these are fast as they can be so that our API feels snappy.

You can write data in your API in many different ways, but my preferred approach is to use background jobs and return quickly. This means you can worry about the logic around how things are created in your own time rather than your clients. The benefit is that your background jobs can still publish updates through web sockets for a real-time feel.

Let’s look at the updated StoreController for accounts when we use this approach:

final class StoreController

{

public function __construct(

private readonly Gate $access,

private readonly Authenticatable $user,

) {}

 

public function __invoke(StoreRequest $request): Responsable

{

if (! $this->access->allows('store')) {

// respond with an error.

}

 

dispatch(new CreateAccount(

payload: NewAccount::from($request->validated()),

user: $this->user->getAuthIdentifier(),

));

 

// the rest of the controller goes here.

}

}

We are sending our background job a payload of a Data Transfer Object, which will be serialized on the queue. We created this DTO using the validated data and want to send it through the user ID because we need to know who to make this for.

Following this approach, we have valid data and type-safe data being passed through to create the model. In our tests, all we need to do here is ensure that the job is dispatched.

it('dispatches a background job for creation', function (string $string): void {

Bus::fake();

 

actingAs(User::factory()->create())->postJson(

uri: action(StoreController::class),

data: [

'name' => $string,

],

)->assertStatus(

status: Http::ACCEPTED->value,

);

 

Bus::assertDispatched(CreateAccount::class);

})->with('strings');

We are testing here to ensure that we pass validation, get the correct status code back from our API, and then confirm that the right background job is dispatched.

After this, we can test the job in isolation because it doesn’t need to be included in our endpoint test. Now, how will this be written to the database? We use a Command class to write our data. I use this approach because using only Action classes is messy. We end up with 100s of action classes that are hard to parse when looking for a specific one in our directory.

As always, because I love to use Dependency Injection, we need to create the interface we will use to resolve our implementation.

interface CreateNewAccountContract

{

public function handle(NewAccount $payload, string $user): Model;

}

We use the New Account DTO as the payload and pass through the user ID as a string. Typically, I give this as a string; I would use a UUID or ULID for the ID field in my applications.

final class CreateNewAccount implements CreateNewAccountContract

{

public function handle(NewAccount $payload, string $user): Model

{

return DB::transaction(

callback: fn (): Model => Account::query()->create(

attributes: [

...$payload->toArray(),

'user_id' => $user,

],

),

);

}

}

We wrap our write action in a database transaction so that we only commit to the database if the write is successful. It allows us to roll back and throw an exception should the write be unsuccessful.

We have covered how to transform model data for our response, how to query and write data, as well as how we want to authorize users in the application. The final stage for building a solid API in Laravel is looking at how we respond as an API.

Most APIs suck when it comes to responding. It is ironic as it is perhaps the most essential part of an API. In Laravel, there are multiple ways in which you can respond, from using helper functions to returning new instances of JsonResponse. I, however, like to build out dedicated Response classes. These are similar to Query and Command classes, which aim to reduce code duplication but are also the most predictable way to return a response.

The first response I create is a collection response, which I would use when returning a list of accounts owned by the authenticated user. I would also make a collection of other responses, from single model responses to empty responses and error responses.

class Response implements Responsable

{

public function toResponse(): JsonResponse

{

return new JsonResponse(

data: $this->data,

status: $this->status->value,

);

}

}

We first must create the initial response that our response classes will extend. This is because they will all respond in the same way. They all need to return the data and the status code – in the same way. So now, let us look at the collection response class itself.

final class CollectionResponse extends Response

{

public function __construct(

private readonly JsonApiResourceCollection $data,

private readonly Http $status = Http::OK,

) {}

}

This is super clean and easy to implement moving forward, and you can turn the data property into a union type to be more flexible.

final class CollectionResponse extends Response

{

public function __construct(

private readonly Collection|JsonResource|JsonApiResourceCollection $data,

private readonly Http $status = Http::OK,

) {}

}

These are clean and easy to understand, so let us look at the final implementation for the IndexController for accounts.

final class IndexController

{

public function __construct(

private readonly Authenticatable $user,

private readonly FilterForUserContract $query,

) {}

 

public function __invoke(Request $request): Responsable

{

$accounts = $this->query->handle(

query: Account::query()->latest(),

user: $this->user->getAuthIdentifier(),

);

 

return new CollectionResponse(

data: $accounts->paginate(),

);

}

}

Focusing on these critical areas allows you to scale your API in complexity without worrying about code duplication. These are the key areas that I will always focus on when trying to figure out what is causing a Laravel API to be slow.

This is by no means an exhaustive tutorial or list of what you need to focus on, but following this somewhat short guide, you can set yourself up for success moving forwards.

Laravel News

US Marines Outsmart AI Security Cameras by Hiding in a Cardboard Box

United States Marines outsmarted artificially intelligent (AI) security cameras by hiding in a cardboard box and standing behind trees. From a report: Former Pentagon policy analyst Paul Scharre has recalled the story in his upcoming book Four Battlegrounds: Power in the Age of Artificial Intelligence. In the book, Scharre recounts how the U.S. Army was testing AI monitoring systems and decided to use the Marines to help build the algorithms that the security cameras would use. They then attempted to put the AI system to the test and see if the squad of Marines could find new ways to avoid detection and evade the cameras. To train the AI, the security cameras, which were developed by Defense Advanced Research Projects Agency’s (DARPA) Squad X program, required data in the form of a squad of Marines spending six days walking around in front of them. After six days spent training the algorithm, the Marines decided to put the AI security cameras to the test. "If any Marines could get all the way in and touch this robot without being detected, they would win. I wanted to see, game on, what would happen," DARPA deputy director Phil Root tells Scharre in the book. Within a single day, the Marines had worked out the best way to sneak around an AI monitoring system and avoid detection by the cameras. Root says: "Eight Marines — not a single one got detected." According to Scharre’s book, a pair of marines "somersaulted for 300 meters" to approach the sensor and "never got detected" by the camera.


Read more of this story at Slashdot.

Slashdot

Adhesives

https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F15a5cb1e-d849-441e-8865-998c6b2d283d_400x400.webp

Once a week we’ll send out a page from Cool Tools: A Catalog of Possibilities. The tools might be outdated or obsolete, but the possibilities they inspire are new. Sign up here to get Tools for Possibilities a week early in your inbox.

Flexible epoxy

3M Scotch-Weld 3532

This is as close to “bombproof” as I have found a glue to be. It seems to stick to just about anything, although 3M says it’s for metals and plastics. I have used it for gluing D-rings – and other things – into my whitewater canoes.

The rings have been able to hold me boiling through big rapids, often upside-down. For this application the glue joint needs to be flexible and waterproof…and this stuff hasn’t ever failed me. How it is different from epoxy: Fills gaps. Flexes under stress without giving away. Sticks to smooth plastics like PVC or vinyl. Seems a LOT stronger than epoxies. You’ll have to find this in a specialty store or order it over the web. Shelf life is 1 year. — Fen Sartorius


Mixes up epoxy

3M Scotch-Weld EPX Applicator

I always used to buy epoxy locally in disposable dispensers that are supposed to dispense equal ratios of the components. The dispensers never work that well: one side always starts to move first and then to get a reasonably equal mix I have to mix up a lot more than I need.

The 3M duo-pack adhesives are sold separately from the dispenser. Because the dispenser is not disposable, it can be a decently built tool, like a caulk gun for epoxy.

The way it works is that you slip on the adhesive cartridge. The applicator has a plunger that pushes up the adhesive cartridge. Think caulk gun. The epoxy comes in double tubes like a doubled tube of caulk. When an adhesive has a different mixing ratio the tubes in the cartridge have different diameters. And there is a different plunger that fits in the tube. The supported mixing ratios are 1:1, 1:2 and 1:10 because those are the ratios of adhesives available. When you buy the system you get the first two plungers, but the 1:10 plunger is sold separately as it is used only for DP-8005 and DP-8010, I think. Just like a caulk gun you can, but you need not remove the adhesive cartridge between uses. The gun stays clean. There is no need to clean it. (Unlike a caulk gun, the adhesive doesn’t leak out the back and get on the gun.)

In fact, if you’re not so worried about waste there’s even a further convenience: static mixing nozzles. These nozzles attach to the end of the epoxy tube and do all the mixing for you so that it really works like a caulk gun: what comes out is ready to use, completely mixed epoxy.

But even if you don’t use the somewhat wasteful mixing nozzles you can still use the gun to extrude the correct ratio mix of 3M adhesive products and then hand mix. I have been able to mix up just the amount of epoxy I need when with the old system I would have mixed ten times what I needed. (No exaggeration here.)

I first got this system because I was trying to glue zinc-plated magnets to polyethylene. I tried regular epoxy. It doesn’t stick well to either one of these materials. There are two adhesives that I think are of particular note in the 3M lineup.

The DP-190 (which I have only used a tiny bit) is supposed to stick to everything except the “low surface energy” plastics. I saw that it is recommended for use with the zinc-plated rare earth magnets (by the magnet sellers). The DP-8005 is designed to stick to low surface energy plastics. I got it for my application.

I also got a small mat made out of teflon because nothing is supposed to stick to that. This was great for repairs using epoxy. I repaired something and laid it on the teflon and it peeled right off after it was cured.

According to 3M, epoxy shelf life is less than a couple years, so you don’t want to buy a lifetime supply at any given time. The shelf life of DP-8005 is only 6 months. The shelf life of the Scotch-Weld Two Part Urethane is 1 year. — Adrian M.

McMaster-Carr sells a very similar product much cheaper, half the cost, for $23. It does not use 3M cartridges. I have had good experiences with Lord adhesives that this gun does use. — KK


Best source for magnets

SuperMagnetMan, supermagnetman.net

I have been buying Neodymium Iron Boron (NIB) super magnets for years. Back then, Wondermagnets was the only source for hobbyists and they had quite a have changed. For the past five years, I have been ordering my magnets from “Mr. George the SuperMagnetMan,” unequivocally the best source today. His prices are the best on the net. His selection is vast: no one else has the stock he has or the variations in size of commonly available shapes. This is no exaggeration or hype. He’s got stuff you can’t get anywhere else and is constantly adding new items, like axially- and diametrically-magnetized NIB wedding rings and radially-magnetized ring magnets. He has magnets so large they are dangerous (fortunately he has put videos on YouTube that show you how to safely handle these monsters — with large leather welding gloves and a special wooden wedge and a 2×4!). He also sells magnetic hooks, pyramid shaped magnets, magnetic jewelry, teflon coated magnets, heart, star, and triangle magnets. You can even get powdered magnets that act like iron filings on steroids! You name it he’s got it. Most magnets are N45-N50 grade, the highest strength you can buy.

Some of the products I have ordered are the magnet powders, radially-magnetized ring magnet, various size sphere magnets, conical magnets, large rectangular magnets, cubes, and many others. Shipping charges are reasonable. Service is great. One time I ordered a bunch of stuff and never completely checked what I got. I went to use one of the magnets months later and found out it was the wrong size. He sent me the right size in the mail a few days after I emailed him.

Mr. George seems like a pretty cool dude, too. An electrical engineer, Mr. George develops magnet products himself and caters to other engineers, inventors, and hobbyists. He can have custom magnets made to order. He has also put up a series of educational videos on YouTube and has done a lot of work with kids. He has a saying, something like, “Give a kid a magnet and you have a friend for life.” — Laral


A strong hold on brake fluid

Seal-All Adhesive & Sealant

Like other adhesives, this one can be used on metals, glass, wood and leather, but it is the only household product I have ever used that will withstand constant exposure to gasoline and/or brake fluid. J-B-WELD will work in some cases, but you have to thoroughly clean and dry the surface or it will fail. Seal-All will seal a leak in a master cylinder-reservoir (non-pressure side) even if you apply it over brake fluid that has already wept out onto the surface. I have also used it to seal an old Coleman fuel tank, and also a weeping fuel fitting on the bottom of a gasoline tank on my bike. This stuff is not what I would consider a toolbox item, but I ride my bike far from home on occasion, and this is one of the items I like to keep in the “just-in-case” bag. — Jackie Gregory


Squeezes tubes dry

Tube-Grip Dispensing Plier

This Tube-Grip easily squeeze tubes of adhesive, calk, sealant, etc. with more precision, less waste with better finished results than other methods. Learning curve is short for starting and stopping applications. Tubes are squeezed beginning from the tube’s bottom seam, and 96% use of product efficiency is claimed. Very thrifty.

Mechanical advantage is claimed to be ten times more than by hand whether gripping vs. pinching. Less fatigue, more control. Concentration on product flow is enhanced because less physical effort is used during application. Tube squeezers for toothpaste and art paint are a different category. Some calling projects are too small for standard tubes of calk, or are in confined areas where a large gun won’t fit.

Tent seam sealing with drippy sealer is controlled better with whole arm movements and a hand grip vs. finger squeezing. I’ve used this 2” dispensing plier for at least 5-years and would not consider many squeeze tube projects without it. A 2 1/2” model also exists. — David McKenzie

Cool Tools

Adhesives

https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F15a5cb1e-d849-441e-8865-998c6b2d283d_400x400.webp

Once a week we’ll send out a page from Cool Tools: A Catalog of Possibilities. The tools might be outdated or obsolete, but the possibilities they inspire are new. Sign up here to get Tools for Possibilities a week early in your inbox.

Flexible epoxy

3M Scotch-Weld 3532

This is as close to “bombproof” as I have found a glue to be. It seems to stick to just about anything, although 3M says it’s for metals and plastics. I have used it for gluing D-rings – and other things – into my whitewater canoes.

The rings have been able to hold me boiling through big rapids, often upside-down. For this application the glue joint needs to be flexible and waterproof…and this stuff hasn’t ever failed me. How it is different from epoxy: Fills gaps. Flexes under stress without giving away. Sticks to smooth plastics like PVC or vinyl. Seems a LOT stronger than epoxies. You’ll have to find this in a specialty store or order it over the web. Shelf life is 1 year. — Fen Sartorius


Mixes up epoxy

3M Scotch-Weld EPX Applicator

I always used to buy epoxy locally in disposable dispensers that are supposed to dispense equal ratios of the components. The dispensers never work that well: one side always starts to move first and then to get a reasonably equal mix I have to mix up a lot more than I need.

The 3M duo-pack adhesives are sold separately from the dispenser. Because the dispenser is not disposable, it can be a decently built tool, like a caulk gun for epoxy.

The way it works is that you slip on the adhesive cartridge. The applicator has a plunger that pushes up the adhesive cartridge. Think caulk gun. The epoxy comes in double tubes like a doubled tube of caulk. When an adhesive has a different mixing ratio the tubes in the cartridge have different diameters. And there is a different plunger that fits in the tube. The supported mixing ratios are 1:1, 1:2 and 1:10 because those are the ratios of adhesives available. When you buy the system you get the first two plungers, but the 1:10 plunger is sold separately as it is used only for DP-8005 and DP-8010, I think. Just like a caulk gun you can, but you need not remove the adhesive cartridge between uses. The gun stays clean. There is no need to clean it. (Unlike a caulk gun, the adhesive doesn’t leak out the back and get on the gun.)

In fact, if you’re not so worried about waste there’s even a further convenience: static mixing nozzles. These nozzles attach to the end of the epoxy tube and do all the mixing for you so that it really works like a caulk gun: what comes out is ready to use, completely mixed epoxy.

But even if you don’t use the somewhat wasteful mixing nozzles you can still use the gun to extrude the correct ratio mix of 3M adhesive products and then hand mix. I have been able to mix up just the amount of epoxy I need when with the old system I would have mixed ten times what I needed. (No exaggeration here.)

I first got this system because I was trying to glue zinc-plated magnets to polyethylene. I tried regular epoxy. It doesn’t stick well to either one of these materials. There are two adhesives that I think are of particular note in the 3M lineup.

The DP-190 (which I have only used a tiny bit) is supposed to stick to everything except the “low surface energy” plastics. I saw that it is recommended for use with the zinc-plated rare earth magnets (by the magnet sellers). The DP-8005 is designed to stick to low surface energy plastics. I got it for my application.

I also got a small mat made out of teflon because nothing is supposed to stick to that. This was great for repairs using epoxy. I repaired something and laid it on the teflon and it peeled right off after it was cured.

According to 3M, epoxy shelf life is less than a couple years, so you don’t want to buy a lifetime supply at any given time. The shelf life of DP-8005 is only 6 months. The shelf life of the Scotch-Weld Two Part Urethane is 1 year. — Adrian M.

McMaster-Carr sells a very similar product much cheaper, half the cost, for $23. It does not use 3M cartridges. I have had good experiences with Lord adhesives that this gun does use. — KK


Best source for magnets

SuperMagnetMan, supermagnetman.net

I have been buying Neodymium Iron Boron (NIB) super magnets for years. Back then, Wondermagnets was the only source for hobbyists and they had quite a have changed. For the past five years, I have been ordering my magnets from “Mr. George the SuperMagnetMan,” unequivocally the best source today. His prices are the best on the net. His selection is vast: no one else has the stock he has or the variations in size of commonly available shapes. This is no exaggeration or hype. He’s got stuff you can’t get anywhere else and is constantly adding new items, like axially- and diametrically-magnetized NIB wedding rings and radially-magnetized ring magnets. He has magnets so large they are dangerous (fortunately he has put videos on YouTube that show you how to safely handle these monsters — with large leather welding gloves and a special wooden wedge and a 2×4!). He also sells magnetic hooks, pyramid shaped magnets, magnetic jewelry, teflon coated magnets, heart, star, and triangle magnets. You can even get powdered magnets that act like iron filings on steroids! You name it he’s got it. Most magnets are N45-N50 grade, the highest strength you can buy.

Some of the products I have ordered are the magnet powders, radially-magnetized ring magnet, various size sphere magnets, conical magnets, large rectangular magnets, cubes, and many others. Shipping charges are reasonable. Service is great. One time I ordered a bunch of stuff and never completely checked what I got. I went to use one of the magnets months later and found out it was the wrong size. He sent me the right size in the mail a few days after I emailed him.

Mr. George seems like a pretty cool dude, too. An electrical engineer, Mr. George develops magnet products himself and caters to other engineers, inventors, and hobbyists. He can have custom magnets made to order. He has also put up a series of educational videos on YouTube and has done a lot of work with kids. He has a saying, something like, “Give a kid a magnet and you have a friend for life.” — Laral


A strong hold on brake fluid

Seal-All Adhesive & Sealant

Like other adhesives, this one can be used on metals, glass, wood and leather, but it is the only household product I have ever used that will withstand constant exposure to gasoline and/or brake fluid. J-B-WELD will work in some cases, but you have to thoroughly clean and dry the surface or it will fail. Seal-All will seal a leak in a master cylinder-reservoir (non-pressure side) even if you apply it over brake fluid that has already wept out onto the surface. I have also used it to seal an old Coleman fuel tank, and also a weeping fuel fitting on the bottom of a gasoline tank on my bike. This stuff is not what I would consider a toolbox item, but I ride my bike far from home on occasion, and this is one of the items I like to keep in the “just-in-case” bag. — Jackie Gregory


Squeezes tubes dry

Tube-Grip Dispensing Plier

This Tube-Grip easily squeeze tubes of adhesive, calk, sealant, etc. with more precision, less waste with better finished results than other methods. Learning curve is short for starting and stopping applications. Tubes are squeezed beginning from the tube’s bottom seam, and 96% use of product efficiency is claimed. Very thrifty.

Mechanical advantage is claimed to be ten times more than by hand whether gripping vs. pinching. Less fatigue, more control. Concentration on product flow is enhanced because less physical effort is used during application. Tube squeezers for toothpaste and art paint are a different category. Some calling projects are too small for standard tubes of calk, or are in confined areas where a large gun won’t fit.

Tent seam sealing with drippy sealer is controlled better with whole arm movements and a hand grip vs. finger squeezing. I’ve used this 2” dispensing plier for at least 5-years and would not consider many squeeze tube projects without it. A 2 1/2” model also exists. — David McKenzie

Cool Tools

The weapon that changed warfare

https://GunFreeZone.net/wp-content/uploads/2023/01/evan-matchlock-1.jpg

Matchlock .72 caliber . Shooting a .69 caliber round ball with a 180 grain charge of 1F.

It is a cumbersome animal, incredibly slow to load and shoot, dangerous manipulation but so much fun to shoot. In the words of Leeloo: “Big Badaboom!”

 

Gun Free Zone

McFly Is the Best Way to Repeat Linux Commands From Your Bash History

https://static1.makeuseofimages.com/wordpress/wp-content/uploads/2023/01/access-linux-command-history-with-mcfly-1.jpg

Every Linux user knows that the most frequently used key combination is Ctrl + R. You use it to search through your Bash history for some fragment of text you’ve previously inputted into the terminal, hitting the combo again and again until you find the command you need.

Stop your keycaps from wearing out by using McFly—a neural network-powered shell history search replacement, that takes your working directory and the context of recently executed commands into account.

Why Should You Use McFly to Search Your Shell History?

If you’ve been using Linux for any amount of time, you probably spend a good portion of your day on the command line. Whether you’re listening to internet radio, creating mind maps for your next project, or setting up a self-hosted workout and fitness manager, the Linux terminal is where you make the magic happen.

Many times you’ll repeat the same command over and over again, or at least, with slight modifications.

The easiest way to repeat a command is to use reverse-i-search by hitting Ctrl + R, then typing a part of the command. For instance, if you press Ctrl + R, then input:

 ls 

…the reverse-i-search prompt will fill out the most recent command which contained the “ls” string or sub-string. Hit Ctrl + R again, and reverse-i-search will prompt you to use the next most recent, and so on.

You can hit Enter to execute the command, or the left or right arrow keys to edit it before executing.

It’s a great tool, but you can only see one entry at a time, and if you hit the combo one too many times by accident, you have to start again from the beginning.

McFly uses the same key combo as reverse-i-search and has the same basic functionality, but improves on it—allowing you to select from a list of the most likely candidates for the command you want to use, as well as a more intelligent way of making suggestions.

Install McFly as a reverse-i-search Replacement on Linux

Installing McFly is as simple as downloading and running a script created by the McFly developer. Open a terminal, and enter:

 wget https:
sudo sh install.sh

The first command downloads a script to download and install a binary release of a Rust crate hosted on GitHub, and the second command uses this script to download and install McFly.

McFly is now installed, but you can’t use it as a reverse-i-search replacement just yet. Use nano to edit your .bashrc file:

 nano ~/.bashrc 

…and at the end of the file, add:

 eval "$(mcfly init bash)" 

Save and exit nano with Ctrl + O then Ctrl + X.

Close your terminal, then reopen it. Next time you use Ctrl + R, McFly will run in place of reverse-i-search.

Use McFly to Search Your Bash History!

Hit Ctrl + R, and you’ll instantly be in the McFly TUI (terminal user interface) with a blank prompt and a list of 10 most likely commands—so make sure your mum isn’t standing behind you if you frequently use yt-dlp to download anything naughty.

If your desired command is in the list, use the Up and Down arrow keys on your keyboard until your desired entry is highlighted. Press Enter to execute.

If you want to edit the command before launching, highlight the entry, then press the Tab key. You will be returned to the command prompt with the text already entered. Edit the command to suit your needs, then press Enter.

McFly employs a simple neural network to try and figure out what command you’re looking for. This takes into account variables such as what directory you’re currently in, how often you run the command, whether the command usually executes successfully, whether you’ve selected the command in McFly before, and when you last used the command.

While this usually works well and makes it easy to find the command you want to use, you may want to turn this feature off. Pressing F1 from within the McFly TUI will toggle the sorting mechanism to one based on time.

If there’s an embarrassing, compromising, or less-than-useful command you want to delete from your history entirely, highlight it and press F2.

Use Your Linux Terminal More Effectively

Now you can efficiently search and execute commands from your Bash history; it’s worthwhile replacing some old favorites from the 1970s with their modern alternatives.

Use bat instead of cat, duf instead of df, and btop instead of top or htop!

MakeUseOf

Smith & Wesson M&P9 M2.0 Metal Review: Best All Metal 9mm?

https://www.pewpewtactical.com/wp-content/uploads/2023/01/Smith-Wesson-MP-9-M2-0-Metal-pose-right.jpg


Metal-framed pistols are making a comeback, with a handful of manufacturers slowly introducing metal versions of their most popular guns.

So, it’s no surprise that Smith & Wesson would jump into the metal resurgence with a new addition to its famed M&P series.

Smith & Wesson M2.0 Metal

The M&P M2.0 Metal uses the company’s solid platform but ditches polymer for an aluminum frame and adds on some upgraded features as well.

We got our hands on the Metal and took it to the range to see if it improved the M&P series. Spoiler alert, it does!

But stick around and keep reading to see what sold us on the Metal.

Table of Contents

Loading…

Smith & Wesson M2.0 Metal Review at a Glance

Pros

  • Accurate
  • Good ergonomics
  • Handsome

Cons

  • Above average price

The Bottom Line

Form and function are often at odds with each other in the firearms world. What works well doesn’t always end up being very pretty. There are a lot of examples to support this theory. The Smith & Wesson M2.0 Metal is not one of them.

The M&P 2.0 Metal is a great combination of show and go. It looks great but is also accurate and reliable.

Specs & Features

Specs

  • Caliber: 9mm
  • Capacity: 17+1
  • Action: Striker fired semi-auto
  • Length: 7.25”
  • Barrel Length: 4.25”
  • Height: 5.5”
  • Width: 1.3”
  • Weight: 1.76 lbs.
  • Comes With: Cardboard box, two 17-round magazines, 6 optic plates & screws, 4 grip panels, lock, manual.

Features

  • Flat face trigger
  • 18-degree grip angle
  • Textured polymer grip

Source: Smith & Wesson

Available Coupons

Background

Smith & Wesson was founded in 1852, and the M&P line started over 100 years ago. There is a lot of history here.

M&P was originally marketed toward the military and police, but the general shooting public found love for the line of firearms those professions could trust.

M&P 9 M2.0 glamour
M&P 9 M2.0

In my own LE career, I never used an M&P, and when I first tried it, I didn’t like the trigger because it felt squishy compared to what I was used to.

After I stuck with it for a while, though, I realized how wrong I was.

The guns are great, and the trigger greatly contributes to the accuracy, as I found out in this review of the M&P 2.0.


Rating score

4.9

3 ratings

Who Is It For?

The M2.0 Metal is a cut above the average handgun. It’s certainly still worthy of its namesake heritage, so it would make a fine defensive handgun for just about anyone.

The model we tested is full size and came in at just over 7 inches long, so keep that in mind when considering concealment.

Fit & Feel

The gun feels outstanding in the hand — light and well-balanced, with a slight tip toward the business end.

Its aggressive texture of the polymer front strap and back strap really helps keep the pistol firmly in hand during recoil and manipulation.

The trigger bow has a light curve and a nice, flat-face surface that is comfortable to use.

There’s quite a bit of pre-travel before hitting a defined wall that broke at an average of 3 pounds, 14 ounces — reset was a little softer than I prefer, but was still tactile, though barely audible.

Its magazines are steel with a large plastic base pad that allows you to grab onto them when seated should a malfunction occur and stripping become necessary. They included a light grey follower that was clearly visible when the slide locked back.

In addition, the grip features beveled angles on the interior, which guide magazines in for seating. The external size isn’t flared, but you’re getting some assistance regardless.

Sights are also metal (an ongoing theme) in a white, 3-dot configuration and include serrations on the rear block. Both front and rear are held in place with a dovetail and are replaceable.

How Does It Shoot?

I shot several 3-shot groups for accuracy at 7 yards and was very impressed. The groups were all very close, with some holes even touching.

The trigger, once mastered, really allows the shooter to get on, then break the shot without disturbing the gun. This is achieved by holding the trigger back to the wall, finalizing the sight picture, then pressing the rest of the way like a two-stage trigger.

I was able to ride the dot through the recoil thanks to the aggressive grip texture and found the M2.0 pointed naturally with the 18-degree angle. This made follow-up shots quicker.

What Sets it Apart?

The M2.0 Metal has a T6 aluminum frame, different from the polymer versions of the old. This makes the gun slightly heavier as a result. This isn’t a bad thing, though.

I feel like the minimally additional weight helped me to control the recoil a little better. Another thematic difference is going to be the Tungsten Gray Cerekote color, which I find to be marvelous.

This version is also compatible with previous M&P models of similar size in both magazines and holsters.

It also has forward slide serrations!

I also enjoyed having everything I needed to mount several different optics in the box.

That said, the plates are plastic, so I’m curious to see how they’ll do long term.

By the Numbers

Reliability: 5/5

With approximately 500 rounds downrange, we experienced zero issues. Magazines fed cleanly, dropped clearly, and the gun fired and extracted as expected.

Ergonomics: 5/5

The M2.0 Metal has nice curves on the grip that fit even my large hands well, plus the beavertail was just enough to protect my hands from the slide. Controls were easy to reach, and the magazine release is reversible for lefties.

Accuracy: 5/5

Three nearly touching rounds at 21 feet are pretty darn good and only reveal the limitations of this shooter. The M2.0, like previous iterations, is accurate.

Customization: 5/5

Having been around for quite some time, the M&P line enjoys strong support in the aftermarket. Shooters have a lot of options to customize to their heart’s content.

Value: 4/5

The current MSRP listed on the Smith & Wesson website is $899 though several web prices have the M2.0 Metal listed at around $850. That’s a little steep compared to the average handgun, but this gun is above average in looks and performance.

Overall: 5/5

599

at Kygunco

Prices accurate at time of writing

Prices accurate at time of writing

Available Coupons

Upgrades for M2.0 Metal

For this review, we mounted a Trijicon RMR.

Best Pistol Red Dot
475

at Brownells

Prices accurate at time of writing

Prices accurate at time of writing

Available Coupons

While that is a great optic, Holosun just released their new SCS model for the M&P series. Either would be an excellent choice.

349

at Amazon

Prices accurate at time of writing

Prices accurate at time of writing

Available Coupons

Another critical upgrade would be a light; we’re stoked about Holosun’s new P.ID.

114

at OpticsPlanet

Prices accurate at time of writing

Prices accurate at time of writing

Available Coupons

Final Verdict

You can have your cake and eat it too. The cost is a little above the median, but our testing revealed a handgun that is reliable, accurate, and beautiful.

Whether you’re an officer on the street or a citizen concerned with your safety and that of those around you, the M2.0 Metal is a great choice.

Will you be picking up an M&P9 M2.0 Metal? Let us know in the comments below! And for more metal options, check out our Best Metal Framed Guns!

The post Smith & Wesson M&P9 M2.0 Metal Review: Best All Metal 9mm? appeared first on Pew Pew Tactical.

Pew Pew Tactical

Whalesync, a Seattle startup syncing data between software apps, raises $1.8M

https://cdn.geekwire.com/wp-content/uploads/2023/01/Screen-Shot-2023-01-26-at-4.26.40-PM-2048×1151.png

(Whalesync Photo)

Whalesync, a Seattle startup offering no-code support to companies to sync their data between software applications, raised $1.8 million.

The startup is led by CEO Curtis Fonger and co-founder Matthew Busel. Fonger previously founded Appetas, a Seattle startup that helped restaurant owners create customizable websites with integration to delivery services like OpenTable and GrubHub.

Appetas was bought by Google in 2014, where Fonger worked as an engineer for six years.

Busel previously worked as a product manager at MakeSpace, then was a software consultant at Thylacine Capital. Before that, he founded Referralboard, a Slack integration that let users earn points by referring employees to their managers.

The duo met during Y Combinator’s founder matching platform, becoming the first startup whose founders graduated YC’s accelerator after meeting through the networking program.

Whalesync sells a no-code tool that lets businesses sync their data across different software apps, allowing businesses to manage all of their inputs from a single spreadsheet.

Large enterprises are currently using processes like ETL (extract, transfer, load) and reverse-ETL pipelines to move data in and out of data warehouses, Busel told GeekWire.

“We’ve learned from these best practices and created novel technology to simplify the setup process and bring the power of data syncing to SMBs, who are currently using automation tools to send data between applications,” he said in an email.

Busel declined to share revenue figures but said the company has already signed up “hundreds of customers.” Some of its early use cases include Alchemy’s Dapp Store, which uses Whalesync’s tech to sync its Airtable and Webflow, as well as powering Webflow’s events calendar.

Whalesync will compete with large file syncing companies like Zapier, as well as HubSpot, which acquired the data synchronization platform PieSync in 2019.

The pre-seed funding comes from YC, Ascend, Liquid2, Soma, and others.

GeekWire

‘Minecraft Legends’ brings blocky base-building action to Xbox and PC on April 18th

http://img.youtube.com/vi/lw6f-tJKoao/0.jpg

Minecraft Legends, the unique action-strategy spin on Microsoft’s block-building franchise, will arrive on Xbox consoles and PCs on April 18th. Announced last June, the game resembles a modern spin on classic Warcraft strategy: Your goal is to protect your base and destroy your enemy’s. It’ll feature online campaign co-op and competitive multiplayer, as you’d expect. And judging from the most recent trailer, it looks compelling enough to tempt over gamers who could never figure out what to do in the original Minecraft.

Engadget

The Ballot Box is Gone


The battle for the nation’s electorate is over, and the statists have won. How did they do it? By realizing that it isn’t VOTERS that are required to win elections, nor is it VOTES. No, what is required to win elections is BALLOTS. The Republicans still can’t grasp this, and are spending all of their time and efforts in trying to make sure that one person gets one vote.

That’s so old fashioned and last decade.

With their hold on the nation’s governor’s offices firmly established, having added control of the state legislatures in both Michigan and Minnesota, Democrats are going to keep changing election rules nationwide. Their wish list of proposals for 2023 includes expanding automatic voter registration systems, preregistering teenagers to vote, lowering the voting age to 16, granting the franchise to felons, and criminalizing anything that the left disagrees with as “disinformation.” Anyone who opposes these policies will be branded as a racist.

Look at what is happening here- by focusing on the harvesting of ballots instead of votes, the Democrats can get elected, even if and when their policies are unpopular. Automatic voter registration means that everyone is registered to vote, no questions asked. Couple that with automatic mail in balloting where each voter gets mailed a ballot, and you have millions of ballots going out to people who aren’t even aware that they are registered to vote. Why, there are ballots going out to registered voters who aren’t real, living people. Those ballots are being mailed to addresses that don’t even exist.

During the 2020 election, Michigan’s Democratic Secretary of State Jocelyn Benson sent out automatic voter registration forms to all eligible Michigan residents. As a result, 114,000 people were added to Michigan’s voter rolls, with many being fake registrations. By padding state voter rolls with new unlikely voters, Democrats can harvest those ballots and put their candidates over the top. There are 501(c)(3) nonprofit organizations are solely dedicated to this, and we know this because of the FTX scandal.

Don’t expect that to change in 2024. Republicans are playing a losing game akin to playing Monopoly against someone who is the banker and is willing to give themselves interest free loans from the bank. The ballot box is gone. There are laws coming that intend on destroying the soap box. There aren’t all that many boxes left.

Area Ocho