做者:陳希章 發表於 2017年12月19日linux
這一篇文章將用一個完整的實例,給你們介紹如何基於dotnet core(微軟.NET的最新版本,支持跨平臺,跨設備的應用開發,詳情請參考 https://www.microsoft.com/net 開發一個Web API Service,而且利用Azure的PaaS服務來實現部署,以及持續的開發運營(devops)。git
這篇文章的難度不高,但會做爲一個操做指南,後續不少文章,若是涉及到這塊基礎工做,都會引用這篇文章。本文所演示的範例代碼,能夠經過 https://github.com/chenxizhang/dotnetcoreapisample 下載。github
目前的最新版本是2.1.3,你能夠根據須要下載到不一樣的版本,請注意安裝SDK,而不是Runtime。web
這個工具一樣是支持跨平臺的,請經過下面的地址下載安裝:https://code.visualstudio.com/Downloadsql
在命令行工具中運行 dotnet new webapi –o dotnetcoreapisample數據庫
即使不作任何修改,在命令行工具中運行dotnet run便可運行這個項目。macos
在瀏覽器中訪問 http://localhost:5000/api/values 若是你也看到下面的效果,恭喜你,你的項目已經運行成功了。編程
在命令行中輸入 code . 會自動打開Visual Studio Code。若是你打開Controllers目錄下面的ValuesController.cs 文件,你能夠看到以下代碼,跟上面的網頁返回結果對照一下,你會以爲如今編寫一個Web API 真的很是簡單啊。json
雖然上面的代碼能運行,但咱們真正要作的一個Web API服務,是但願能給用戶提供建立訂單,修改訂單,查詢訂單,甚至刪除訂單的服務。因此,請先刪除掉上面這個ValuesController.cs 文件。我會演示怎麼樣一步一步地將一個訂單服務實現出來。windows
全部的服務都離不開數據,咱們將使用Entity Framework來實現數據層服務。因此咱們要先定義訂單這個數據接口的實體。
請增長一個目錄,Models,而後增長第一個代碼文件 Order.cs
namespace dotnetcoreapisample.Models { using System; public class Order{ public int Id { get; set; } public DateTime OrderDate { get; set; } public int Quantity { get; set; } public decimal UnitPrice { get; set; } public string Product { get; set; } } }
光有數據實體是不夠的,咱們還須要定義一個數據服務,或者也能夠成爲數據上下文服務。請在Models目錄中,再建立下面這樣一個類:SampleDbContext.cs
namespace dotnetcoreapisample.Models{ using System; using Microsoft.EntityFrameworkCore; using System.Linq; public class SampleDbContext:DbContext{ public SampleDbContext(DbContextOptions<SampleDbContext> options):base(options){ } public DbSet<Order> Orders { get; set; } } }
dotnet core提供了一種很是好的編程模型,咱們能夠在程序啓動的時候,將必要的數據服務對象注入進去,而後在後續的業務服務中就能夠直接使用它。
定位到Startup.cs這個文件,在頂部先添加兩個命名空間的引用 using Microsoft.EntityFrameworkCore;
和 using dotnetcoreapisample.Models;
而後在 ConfigureServices 這個方法裏面,第一行添加以下代碼 services.AddDbContext<SampleDbContext>(_=>_.UseInMemoryDatabase("Sample"));
這句代碼的意思是,使用一個在內存中的數據庫。做爲快速開發和測試目的,這是最方面的。固然,若是你真的想要有一個實際的數據庫文件,Entity Framework支持幾乎全部的數據源,尤爲是對sqlite和SQL Server的支持很是好,請參考 https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/intro
這是最後一步了,請在Controllers目錄中增長一個OrderController.cs的文件,代碼以下
using Microsoft.AspNetCore.Mvc; using dotnetcoreapisample.Models; using System.Collections.Generic; using System.Linq; namespace dotnetcoreapisample.Controllers { [Route("api/[controller]")] public class OrdersController:Controller{ private SampleDbContext context; public OrdersController(SampleDbContext ctx){ context = ctx; } [HttpGet] public IEnumerable<Order> Get(){ return context.Orders; } [HttpGet("{id}")] public Order Get(int id){ return context.Orders.FirstOrDefault(x=>x.Id == id); } [HttpPost] public void Post([FromBody]Order value){ context.Orders.Add(value); context.SaveChanges(); } [HttpPut("{id}")] public void Put(int id,[FromBody]Order value){ var found = context.Orders.FirstOrDefault(x=>x.Id == id); if(found!=null){ found.OrderDate = value.OrderDate; found.Product =value.Product; found.Quantity =value.Quantity; found.UnitPrice =value.UnitPrice; context.SaveChanges(); } } [HttpDelete("{id}")] public void Delete(int id){ var found = context.Orders.FirstOrDefault(x=>x.Id == id); context.Orders.Remove(found); context.SaveChanges(); } } }
完成上面的工做後,你就能夠經過按下F5鍵(或者執行dotnet run命令)運行這個項目了。我用Fiddler來模擬用戶請求,下面展現了四個不一樣的腳本。
建立訂單
咱們使用POST方法發起請求,地址是http://localhost:5000/api/orders,而後在請求的正文裏面用JSON格式表示一個訂單信息
查詢訂單
咱們使用GET方法發起請求,地址也是http://localhost:5000/api/orders,在請求的頭部裏面設置Content-Type爲application/json
此時咱們能夠看到,系統已經建立了一個訂單,編號爲1(這是自動編號的)。
修改訂單
咱們使用PUT方法發起請求,地址是http://localhost:5000/api/orders/1,在請求的正文裏面,我將要修改的訂單信息用JSON表示,請注意,我將單價從200修改成400
若是再次查詢訂單,你能夠看到數據已經修改了
刪除訂單
最後,咱們能夠經過DELETE方法發起請求,給定地址是 http://localhost:5000/api/orders/1 來完成刪除一個訂單的操做
一切看起來還不錯,接下來給你們介紹一下如何採用Azure雲平臺進行部署,以及經過Azure的PaaS服務實現開發運營一體會(devops)的實踐。
傳統的狀況,開發人員(和測試人員)作到上面這一步,工做就算結束了。他們會將代碼簽入到代碼庫,而後愉快地打卡下班。接下來的工做是什麼呢?運維人員會準備虛擬機,安裝必要的軟件,而後將代碼下載下來,編譯以後將獲得的文件複製到服務器的某個文件夾,沐浴更衣燒香拜佛以後,頗有可能Web服務器能正常地啓動起來,若是不能,他們就要頂着巨大的壓力,跟開發人員打電話,委婉地要求對方幫忙檢查一下問題,可是極可能獲得的答覆是:你是怎麼弄的呢,這個明明在個人機器是跑的好好的?上帝保佑,若是此次部署是成功的,但下次若是要更新一個版本,多是再一次的痛苦的過程。若是說,在之前的時候咱們的軟件更新並不頻繁,這種痛苦仍是能夠接受的話,如今隨着互聯網應用開發模式的興起,業務需求可能三天兩頭的變化,如此的開發運營割裂的情況,是遠遠達不到要求的。這也是業界呼喚有更好的工做方式的一個根本緣由,devops也就是這麼樣興起的。
理論其實並不高深,關鍵看怎麼能有效地實現開發和運維的一體化,很大程度上,這個固然取決於平臺和工具,其根本在於要實現智能和自動化。另外,devops會逼迫咱們從新對應用架構進行一些思考,模組化和微服務化會成爲一個天然而然的選擇。這個我在後面會有專門的文章給你們解讀。本文先用實例來讓你們感覺一下。
我這裏推薦的平臺是微軟的Azure雲平臺,它不只僅是一個強大的IaaS平臺,提供了全球質量保證和安全合規的基礎架構服務(計算,網絡,存儲等),同時更重要的是,它是一個PaaS平臺,對於廣大的業務應用開發人員來講,使用Azure提供的工具,能夠事半功倍地實現devops,將更多精力集中在應用邏輯而不是服務器配置、監測、部署更新等工做上面。
閒話少說,若是你尚未Azure帳號,能夠申請試用。接下來能夠參考個人步驟來看看如何將咱們剛纔建立的這個Web API項目部署到Azure,而且實現基於代碼更新的應用自動發佈。
登陸到Azure的管理門戶後,選擇「應用程序服務」,而後添加一個「Web應用」
在接下來的窗口中完成資源配置,請注意,做爲測試場景的話,你甚至能夠選擇免費的一種應用服務計劃。這裏還能夠打開Application Insight(這個目前也是免費的服務)。
配置這個應用服務的部署選擇,此時逐漸解開了Azure 做爲 devops 平臺的面紗了。在下圖中能夠選擇「本地Git存儲庫」做爲部署源
雖然你能夠看到不少其餘的選項,但本篇文章是入門的,因此不作一一展開。下面咱們設置一下部署的憑據。
完成上面這些配置後,咱們回到Web應用的概述頁面,你會發現如今多出來一個能夠用來遠程部署的Git存儲庫地址,請將這個地址複製下來。
回到以前的Visual Studio Code的界面,打開命令行窗口,經過git init
命令初始化本地的git存儲庫,而後執行git add *
和git commit -m 'init'
這兩條命令完成初始化提交到本地。最後,經過下面的命令添加遠程存儲庫。
接下來,運行 git push azure master
這條命令,此時會彈出一個對話框,請輸入上一步建立的用戶名和密碼,這個提交過程可能會比較長,尤爲是第一次。這是由於它不只僅會將代碼上傳到代碼庫,並且後臺會啓動一系列的操做,來進行編譯和部署。下面是在我這邊的輸出結果。
PS C:\temp\dotnetcoreapisample> git push azure master Counting objects: 9, done. Delta compression using up to 4 threads. Compressing objects: 100% (7/7), done. Writing objects: 100% (9/9), 7.90 KiB | 899.00 KiB/s, done. Total 9 (delta 5), reused 0 (delta 0) remote: Updating branch 'master'. remote: Updating submodules. remote: Preparing deployment for commit id '3adc61d27e'. remote: Generating deployment script. remote: Running deployment command... remote: Handling ASP.NET Core Web Application deployment. remote: ............................................................ remote: Restoring packages for D:\home\site\repository\dotnetcoreapisample.csproj... remote: Restore completed in 755.48 ms for D:\home\site\repository\dotnetcoreapisample.csproj. remote: ..... remote: Generating MSBuild file D:\home\site\repository\obj\dotnetcoreapisample.csproj.nuget.g.props. remote: Generating MSBuild file D:\home\site\repository\obj\dotnetcoreapisample.csproj.nuget.g.targets. remote: Restore completed in 10.36 sec for D:\home\site\repository\dotnetcoreapisample.csproj. remote: ............................................................. remote: Microsoft (R) Build Engine version 15.4.8.50001 for .NET Core remote: Copyright (C) Microsoft Corporation. All rights reserved. remote: remote: ................................................ remote: dotnetcoreapisample -> D:\home\site\repository\bin\Release\netcoreapp2.0\dotnetcoreapisample.dll remote: ........... remote: dotnetcoreapisample -> D:\local\Temp\8d546e10a232b37\ remote: KuduSync.NET from: 'D:\local\Temp\8d546e10a232b37' to: 'D:\home\site\wwwroot' remote: Copying file: 'dotnetcoreapisample.deps.json' remote: Copying file: 'dotnetcoreapisample.dll' remote: Copying file: 'dotnetcoreapisample.pdb' remote: Copying file: 'dotnetcoreapisample.PrecompiledViews.dll' remote: Copying file: 'dotnetcoreapisample.PrecompiledViews.pdb' remote: Copying file: 'dotnetcoreapisample.runtimeconfig.json' remote: Finished successfully. remote: Running post deployment command(s)... remote: Deployment successful. To https://dotnetcoreapisample.scm.azurewebsites.net:443/dotnetcoreapisample.git 37b30a5..3adc61d master -> master
咱們能夠很清楚地看到代碼上傳後,觸發了一個部署的事件,該部署腳本先會拉取全部依賴的包,而後執行構建,最後將文件複製到指定的一個目錄。這種自動化的過程就是devops的基石。固然,如今的dotnet core的平臺無關性也給部署帶來了極大的便利。
在完成部署後,咱們回到Azure的門戶,在應用服務的「部署選項」能夠看到已經部署的記錄,最新的一次部署被標記爲 「活動」狀態。
點擊某一次部署,還能夠看到詳細信息
若是咱們對於當前此次部署不滿意,還能夠隨時選擇其餘部署,而且選擇「從新部署」操做,這樣就能夠快速進行應用的回滾。
好了,咱們最後能夠在瀏覽中輸入 https://dotnetcoreapisample.azurewebsites.net/api/orders ,若是返回一個空白的數組「[]」 ,說明這個服務是正常工做的。由於咱們使用的是內存數據庫,因此每次部署後,都會將數據清空,這就是爲何第一次返回空白數組的緣由。
使用Azure的PaaS服務來部署Web 應用,經過簡單配置後,開發人員只須要關注代碼自己,在本地調試後,將代碼推送到Azure,後臺將自動進行構建和部署,因爲有版本控制,因此隨時能夠根據須要進行前滾和回滾。基於Azure平臺進行應用開發,無縫地融入了devops,能夠極大地改善開發和運維流程,提升研發效率和質量。本文只是一個開始,我在後續還會介紹各類不一樣的場景。