I came across this very interesting article explaining correct use of PATCH in HTTP world. Worth reading even if little out-dated!
https://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/
Skill to do come from doing…
I came across this very interesting article explaining correct use of PATCH in HTTP world. Worth reading even if little out-dated!
https://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/
In this article I’ll walk through creating alias in Windows command line. I will create alias named “subl” for launching Sublime Text 3 editor from command line.
For this purpose, doskey
command is particularly useful.
Sublime Text 3 is installed in default folder on my PC, so running below command will do the trick:
doskey subl="C:\Program Files\Sublime Text 3\sublime_text.exe"
Now I can type
subl
in command prompt and system starts Sublime Text 3 editor.
There is one little catch here though. Even if I type
subl C:\tmp\file.txt
Sublime always opens new blank document.
In order to be able to pass parameter into the alias, doskey command needs to be altered slightly:
doskey subl="C:\Program Files\Sublime Text 3\sublime_text.exe"
$*
Adding “$*” at the end allows the alias to accept zero, one, or more args.
I can now type
subl C:\tmp\file.txt
and Sublime happily loads correct file.
While using this alias, I discovered one very annoying thing: aliases disappear when console is restarted. Doskey command needs to be called again.
There is a way to automate loading Doskey macros (loads of information on this on google), but it requires modifying Windows registry, which I did not want.
Instead I found easier solution:
I created very simple batch file called subl.bat
:
@ECHO OFF
START "" "C:\Program Files\Sublime Text 3\sublime_text.exe" %1
And moved it to location listed in system PATH
variable, i.e. %USERPROFILE%
Now calling
subl \tmp\path.txt
Launches new instance of Sublime Text even after restarting console.
Voila!
Extremely useful compatibility list, especially for debugging purposes:
Excellent reading from Microsoft: https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md
Operation | cmd | PowerShell |
Get a simple directory listing |
dir |
get-childitem alias: dir |
Get a recursive directory listing |
dir /s |
get-childitem -recurse alias: dir -r |
Get a wide directory list |
dir /w |
dir | format-wide alias: dir | fw |
List built-in commands |
help |
get-command alias: help |
Copy a file |
copy foo.txt bar.txt |
copy-item foo.txt bar.txt alias: copy foo.txt bar.txt |
Move a file |
move foo.txt c:\ |
move-item foo.txt d:\ alias: move foo.txt d:\ |
Rename a file |
ren foo.txt bar.txt |
rename-item foo.txt bar.txt alias: ren foo.txt bar.txt |
Batch rename |
ren *.one *.two |
dir *.pdf | rename -newname {$_.name -rep ".one",".two"} |
Set the current directory to d:\ |
d: cd \ |
set-location d:\ alias: cd d:\ |
Clear the screen |
cls |
clear-host alias: cls |
List only directories |
dir /ad |
dir | where { $_.MshIsContainer } |
Directory list, sorted by date |
dir /od |
dir | sort-object LastWriteTime |
Directory list, sorted by date, descending order |
dir /o-d |
dir | sort-object LastWriteTime -desc |
Show the current directory |
cd |
get-location alias: pwd |
See a command’s help |
dir /? |
get-help get-command or: get-help get-command -detailed or: get-help get-command -full or: dir -? |
List environment variables |
set |
dir env: |
Delete a file |
del foo.txt |
remove-item foo.txt alias: del foo.txt |
Find all *.txt files |
dir /s *.txt |
get-childitem -recurse -include *.txt alias: dir -r -i *.txt |
Find all *.txt files containing a particular string |
findstr "foo" *.txt |
dir *.txt | select-string "foo" |
Show a list of services |
net start |
get-service |
Start a service |
net start MyService |
start-service MyService |
Stop a service |
net stop MyService |
stop-service MyService |
Show network shares |
net share |
gwmi Win32_Share |
Show a list of running processes |
tasklist |
get-process alias: ps |
Kill all notepad.exe processes |
taskkill /im notepad.exe /f |
ps notepad | kill |
d | day of the month as a number from 1 through 31 – a single-digit day is formatted without a leading zero |
dd | day of the month as a number from 01 through 31 – a single-digit day is formatted with a leading zero |
ddd | abbreviated name of the day of the week (Mon, Tues, Wed etc) |
dddd | full name of the day of the week (Monday, Tuesday etc) |
h | 12-hour clock hour (e.g. 7) |
hh | 12-hour clock, with a leading 0 (e.g. 07) |
H | 24-hour clock hour (e.g. 19) |
HH | 24-hour clock hour, with a leading 0 (e.g. 19) |
m | minutes |
mm | minutes with a leading zero |
M | month number |
MM | month number with leading zero |
MMM | abbreviated Month Name (e.g. Dec) |
MMMM | full month name (e.g. December) |
s | seconds |
ss | seconds with leading zero |
t | abbreviated AM / PM (e.g. A or P) |
tt | AM / PM (e.g. AM or PM |
y | year, no leading zero (e.g. 2001 would be 1) |
yy | year, leadin zero (e.g. 2001 would be 01) |
yyy | year, (e.g. 2001 would be 2001) |
yyyy | year, (e.g. 2001 would be 2001) |
K | time zone information of a date and time value (e.g. +05:00) |
z | with DateTime values, represents the signed offset of the local operating system’s time zone from Coordinated Universal Time (UTC), measured in hours. (e.g. +6) |
zz | as z but with leadin zero (e.g. +06) |
zzz | with DateTime values, represents the signed offset of the local operating system’s time zone from UTC, measured in hours and minutes. (e.g. +06:00) |
f | most significant digit of the seconds fraction; that is, it represents the tenths of a second in a date and time value. |
ff | two most significant digits of the seconds fraction; that is, it represents the hundredths of a second in a date and time value |
fff | three most significant digits of the seconds fraction; that is, it represents the milliseconds in a date and time value |
ffff | four most significant digits of the seconds fraction; that is, it represents the ten thousandths of a second in a date and time value |
fffff | five most significant digits of the seconds fraction; that is, it represents the hundred thousandths of a second in a date and time value |
ffffff | six most significant digits of the seconds fraction; that is, it represents the millionths of a second in a date and time value |
the seven most significant digits of the seconds fraction; that is, it represents the ten millionths of a second in a date and time value | |
F | most significant digit of the seconds fraction; that is, it represents the tenths of a second in a date and time value. Nothing is displayed if the digit is zero. |
: | the time separator defined in the current DateTimeFormatInfo..::.TimeSeparator property. This separator is used to differentiate hours, minutes, and seconds. |
/ | date separator defined in the current DateTimeFormatInfo..::.DateSeparator property. This separator is used to differentiate years, months, and days. |
“ | quoted string (quotation mark). Displays the literal value of any string between two quotation marks (“). Your application should precede each quotation mark with an escape character (\). |
‘ | quoted string (apostrophe). Displays the literal value of any string between two apostrophe (‘) characters. |
%c | the result associated with a c custom format specifier, when the custom date and time format string consists solely of that custom format specifier. That is, to use the d, f, F, h, m, s, t, y, z, H, or M custom format specifier by itself, the application should specify %d, %f, %F, %h, %m, %s, %t, %y, %z, %H, or %M. For more information about using a single format specifier, see Using Single Custom Format Specifiers. |
0 | MM/dd/yyyy | 08/22/2006 |
0 | dddd, dd MMMM yyyy | Tuesday, 22 August 2006 |
0 | dddd, dd MMMM yyyy HH:mm | Tuesday, 22 August 2006 06:30 |
1 | dddd, dd MMMM yyyy hh:mm | tt Tuesday, 22 August 2006 06:30 AM |
2 | dddd, dd MMMM yyyy H:mm | Tuesday, 22 August 2006 6:30 |
3 | dddd, dd MMMM yyyy h:mm | tt Tuesday, 22 August 2006 6:30 AM |
0 | dddd, dd MMMM yyyy HH:mm:ss | Tuesday, 22 August 2006 06:30:07 |
0 | MM/dd/yyyy HH:mm | 08/22/2006 06:30 |
1 | MM/dd/yyyy hh:mm | tt 08/22/2006 06:30 AM |
2 | MM/dd/yyyy H:mm | 08/22/2006 6:30 |
3 | MM/dd/yyyy h:mm tt | 08/22/2006 6:30 AM |
0 | MM/dd/yyyy HH:mm:ss | 08/22/2006 06:30:07 |
0 | MMMM dd | August 22 |
0 | ddd, dd MMM yyyy HH’:’mm’:’ss ‘GMT’ | Tue, 22 Aug 2006 06:30:07 GMT |
0 | yyyy’-‘MM’-‘dd’T’HH’:’mm’:’ss | 2006-08-22T06:30:07 |
0 | yyyy’-‘MM’-‘dd HH’:’mm’:’ss’Z’ | 2006-08-22 06:30:07Z |
0 | dddd, dd MMMM yyyy HH:mm:ss | Tuesday, 22 August 2006 06:30:07 |
0 | yyyy MMMM 2006 August |
For an easy understanding use this structure for every resource:
Resource | GET read |
POST create |
PUT update |
DELETE |
/cars | Returns a list of cars | Create a new car | Bulk update of cars | Delete all cars |
/cars/711 | Returns a specific car | Method not allowed (405) | Updates a specific car | Deletes a specific car |
Use PUT, POST and DELETE methods instead of the GET method to alter the state.
Keep it simple and use only plural nouns for all resources.
/users instead of /user
If a resource is related to another resource use subresources.
GET /cars/711/drivers/ Returns a list of drivers for car 711
Both, client and server, need to know which format is used for the communication. The format has to be specified in the HTTP-Header.
Content-Type defines the request format.
Accept defines a list of acceptable response formats.
It is hard to work with an API that ignores error handling. Pure returning of a HTTP 500 with a stacktrace is not very helpful.
Use HTTP status codes
The HTTP standard provides over 70 status codes to describe the return values. We don’t need them all, but there should be used at least a mount of 10.
200 – OK – Eyerything is working
201 – OK – New resource has been created
204 – OK – The resource was successfully deleted
304 – Not Modified – The client can use cached data
400 – Bad Request – The request was invalid or cannot be served. The exact error should be explained in the error payload. E.g. „The JSON is not valid“
401 – Unauthorized – The request requires an user authentication
403 – Forbidden – The server understood the request, but is refusing it or the access is not allowed.
404 – Not found – There is no resource behind the URI.
422 – Unprocessable Entity – Should be used if the server cannot process the enitity, e.g. if an image cannot be formatted or mandatory fields are missing in the payload.
500 – Internal Server Error – API developers should avoid this error. If an error occurs in the global catch blog, the stracktrace should be logged and not returned as response.
Filtering:
Use a unique query parameter for all fields or a query language for filtering.
GET /cars?color=red Returns a list of red cars GET /cars?seats<=2 Returns a list of cars with a maximum of 2 seats
Sorting:
Allow ascending and descending sorting over multiple fields.
GET /cars?sort=-manufactorer,+model
This returns a list of cars sorted by descending manufacturers and ascending models.
Field selection
Mobile clients display just a few attributes in a list. They don’t need all attributes of a resource. Give the API consumer the ability to choose returned fields. This will also reduce the network traffic and speed up the usage of the API.
GET /cars?fields=manufacturer,model,id,color
Paging
Use limit and offset. It is flexible for the user and common in leading databases. The default should be limit=20 and offset=0
GET /cars?offset=10&limit=5
To send the total entries back to the user use the custom HTTP header: X-Total-Count.
Install-Package Swashbuckle.AspNetCore
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
);
Voila!
Few useful SQL tricks:
ALTER SCHEMA targetSchema TRANSFER sourceSchema.tableName
sp_rename 'schemaName.tableName.columnName', 'newColumnName'
This script closes all connections to MS SQL database
USE master; GO ALTER DATABASE dbName SET SINGLE_USER WITH ROLLBACK IMMEDIATE; GO ALTER DATABASE dbName SET MULTI_USER; GO