Fine grain control on Sinatra Routes

At times, you might require fine grain control on the your Sinatra routes.
For example, for the controller path /users/<user_id> , the following would be valid calls –
/users/123 or /users/abc or /users/d6e881d33949470f9df4aa39606d03ea

Now, if you have the user_id as a uuid, you have to validate the user_id every time. Instead of validating the uuid yourself, you could ask Sinatra to reject the request if the provided user_id does not match the uuid pattern.
So, assuming your user_id to be UUID (length 32), instead of defining your controllers as –
put :create, map: ‘/users/:user_id’
you can define them as follows –
put :create, map: %r{/users/(?<user_id>[a-z0-9]{32})}

Notice the <user_id> in the above regular expression. This is match group in a regex and you can get the user_id using the regular params object –
user_id = params[:user_id]

Details here – Sinatra Routes

PUT vs POST while creating a resource

The most asked question and one where I have seen the most inconsistency and interchangeable use in REST APIs is whether to use the HTTP method PUT or POST while designing a REST API to create a User entity.
Usually, I have seen suggestions such as use POST to create and PUT to update, or use POST to create and update.
Though, it depends on how you want to model your APIs and many more factors, the most simplest approach that can get you started and help you to distinguish and decide which HTTP method to use is to know whether –
The Entity’s id is provided by the client, with the API path similar to – /v1/users/{user_id}
OR
The Entity’s id is created on the server, with the API path similar to – /v1/users

If the id is provided by client, you can go for PUT, that is, PUT /v1/users/{user_id}
Else, go for POST, that is POST /v1/users

Note: For a more detailed explanation, refer to this stackoverflow thread