استفاده از API های تحت وب با خروجی XML ؛ به زبان ساده
دنیای اینترنت امروزی، فقط استفاده از وب سایت ها و مطالبشون نیست بلکه وب سایت ها امکانات جانبی دیگری هم ممکنه که برای ما داشته باشند و اصطلاحا میگیم Service خاصی رو ارایه میدند.
سرویس های وب به زبون خیلی ساده به مفهوم به کارگیری امکانات یک وب سایت، در خارج اون وب سایت هست. مثلا شما فرض کنید فروشگاه اینترنتی مورد علاقه شما، امکان این رو داشته باشه که به شما چند خط code بده که شما فرار بدید تو وبلاگتون، و وقتی به وبلاگ خودتون سر میزنید، اون چند خط کد در پشت صحنه به قروشگاه وصل میشن و آخرین محصولات حراجی خورده اونجا رو براتون میارن.. شما اطلاعاتی از اون فروشگاه رو دارید بدون اینکه به وب سایتش رفته باشید!
حالا اگه یه کم همت به خرج بدید، میتونین بگردید تمام فروشگاه هایی که این امکان رو دارند پیدا کنید، و کدهای اونها رو در یک صفحه در یک وب سایت قرار بدید. نتیجه چی میشه؟
شما به سادگی توسط سرویس هایی که وب سایت های فروشگاهی در اختیار شما قرار دادند، یک وبسایت جدید ایجاد کردید، وبسایتی که میشه با مراجعه به اون از آخرین حراجی های مثلا دوازده فروشگاه مختلف، با خبر شد. خیلی خوبه نه؟
یا مثلا سرویس نقشه گوگل که به شما امکان این رو میده که نقشه رو در وب سایت خودتون داشته باشید و به اون اطلاعات جدید به دلخواه خودتون اضافه کنید. یا سایت آمازون امکان استفاده از اطلاعات وب سایتش رو در وب سایت های دیگه میده و به این صورت شما میتونید یک کتابخونه با استفاده از کتابهای آمازون در سایت خودت داشته باشی.
استفاده از سرویس های وب، روز به روز در اینترنت وسعت بیشتری پیدا میکنه تا جایی که با ایجاد زیرساخت های مورد نیاز، اینترنت رو میبره به سمت نسل سوم وب، یعنی اینترنت کاملا هوشمند و پویا. جایی که وب سایت ها با استفاده از سرویس های بی شماری که در اینترنت وجود خواهد داشت، خیلی کار ها رو به صورت هوشمند انجام میدهند، توان تصمیم گیری دارند، و مطالب خودشون رو میتونند بفهمند.
سرویس های وب که به اونها Web API هم میتونیم بگیم ( در اینجا هدف بیان مطلب به صورت کلی و ساده هست، و نه تفاوت WebService و API و پروتکلهای مربوطه ) همینجوری کیلویی قابل استفاده نیست :دی باید چند مورد رو بدونیم تا بتونیم از این سرویس یا API استفاده کنیم. وب سایتی که میخواد سرویس خودش رو ارایه کنه، اطلاعات لازم در این مورد رو حتما باید ارایه بده. اینکه چجوری میشه به سرویس اون متصل شد. پروتکل مورد استفاده چیه و فرمت خروجی و حالت های مختلف در خروجی به چه شکلی هست.
توجه: مثال به کار رفته در این پست، دیگه موجود نیست - اما با خوندن مطلب میتونین بگیرین فضیه چی چیه
با یک مثال میریم جلو... چند روز پیش از طریق یکی از دوستان وب سایتی رو دیدم که با استفاده از API اون، میشه IP رو داد و اسم کشور رو گرفت. آدرس وب سایت اینه:
http://iplocationtools.com/ip_location_api.php
به این وب سایت برید و ببینید که خیلی کامل و ساده نحوه استفاده رو گفته. شما برای گرفتن نام کشوری که متعلق به آی پی 74.125.45.100 هست، کافیست از این آدرس استفاده کنید:
http://iplocationtools.com/ip_query.php?ip=74.125.45.100
به این مدل API ها ، مدل رست (REST) میگیم. در این مدل شما به همون صورت همیشگی که با اینترنت استفاده میکنید، سرویس مورد نظر هم از طریق یک آدرس اینترنتی میتونین استفاده کنید. اگر اون آدرس رو داخل web browser خودتون paste کنید، میبینین خروجی مثل یک فایل XML هست. در واقع وظیفه یک سرویس یا API تحت وب، دادن خروجی از اطلاعات ایجاد شده به یک فرمت مشخص و خام هست و وظیفه ما در این سمت اینه که بعد از دریافت این اطلاعات و پردازش، اونها رو به شکلی که دوست داریم نمایش بدیم.
خوب، طبیعتا ما از این سرویس به این صورت که آدرس رو تایپ کنیم و جواب بگیریم، نمیخواهیم استفاده کنیم! هدف ما در اینجا، ایجاد یک ارتباط با این سرویس، در سورس برنامه هست، و خروجی رو که گرفتیم، اطلاعات رو به فرمت خودمون از اون داده های XML، تولید کنیم.
این کار رو به تعداد انگشتهای دست و پای خودتون و یا شاید چند نفر دیگه میتونین انجام بدید :دی مهم اینه که این چند مورد رو درباره سرویس یا API که میخواهید استفاده کنید، بدونید:
اول: آدرس سرویس و یا API.. در مثال ما: http://iplocationtools.com/ip_query.php
دوم: نحوه انتقال اطلاعات از طرف ما به سرویس.. در مثال ما: پاس دادن آی پی در یک QueryString به آدرس API.. در واقع متد Get در مدل REST .. به این صورت:
http://iplocationtools.com/ip_query.php?ip=74.125.45.100
سوم: نحوه انتقال اطلاعات از سرویس به ما و در واقع خروجی سرویس.. در مثال ما: فرمت XML
در این پست، یکی از چندین راه ممکن رو میبینیم که استفاده از WebClient و XmlDocument هست.
در این مثال، یک کلاس جدید میسازیم به اسم IPtoLocation و در اون یک فانکشن به اسم GetCountry داریم که آی پی رو به عنوان ورودی string داره و خروجی اون، نام کشور به صورت string خواهد بود.
Imports Microsoft.VisualBasic
Public Class IPtoLocation
Public Shared Function GetCountry(ByVal IPAddress As String) As String
End Function
End Class
در مرحله بعد باید به آدرس API وصل شیم و querystring رو که در واقع ورودی تابع ما هست رو به اون آدرس بفرستیم. از کلاس System.Net.WebClient استفاده میکنیم:
Dim apiURLaddress As String = "http://iplocationtools.com/ip_query.php?ip="
Dim webreq As New System.Net.WebClient
Dim outstream As New IO.StreamReader(webreq.OpenRead(apiURLaddress & IPAddress))
ابتدا با استفاده از OpenRead در کلاس WebClient، به آدرس مورد نظر درخواست دادیم، و پاسخ درخواست رو در یک object از نوع StreamReader ریختیم. الان ما یک object داریم به اسم outstream که در حافظه سرور ایجاد شده و حاوی فایل XML هست که پاسخ API به درخواست ما بود. پس مرحله اول که به دست آوردن پاسخ API در متن برنامه بود، به پایان میرسه.
در مرحله بعد باید این فایل XML رو بخونیم. این NameSpace رو در کلاس وارد میکنیم:
Imports System.Xml
و از کلاس XmlDcument برای خوندن متن XML موجود در حافظه توسط outstream، استفاده میکنیم:
Dim xmldoc As New XmlDocument
xmldoc.Load(outstream)
If xmldoc.HasChildNodes Then
Dim rootnode As XmlNode = xmldoc.DocumentElement
If rootnode.SelectSingleNode("Status").ChildNodes(0).Value = "OK" Then
Return rootnode.SelectSingleNode("CountryName").ChildNodes(0).Value
Else
Return rootnode.SelectSingleNode("Status").ChildNodes(0).Value
End If
Else
Return "Error Loading XML file. Maybe Internet Connection is down!"
End If
در اینجا از متد Load استفاده میکنیم و xmldoc رو پر میکنیم از پاسخ برگشتی از API.. چک میکنیم که آیا xmldoc دارای زیرشاخه هست یا نه ( HasChildNodes ). اگر نبود میتونیم نتیجه بگیریم از ابتدا، پاسخی به webclient ما داده نشده که ممکنه به علت مشکل ارتباط اینترنت باشه یا سایت اصلی مثلا مشکل داشته باشه.
در ادامه کار باید از ساختار فایل XML خروجی، اطلاع داشته باشیم. این کار خیلی ساده هست، فقط کافیه آدرس رو دستی خودتون وارد internet browser کنید و خروجی XML رو ببینید که به این صورت هست:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Ip>74.125.45.100</Ip>
<Status>OK</Status>
<CountryCode>US</CountryCode>
<CountryName>United States</CountryName>
<RegionCode>06</RegionCode>
<RegionName>California</RegionName>
<City>Mountain View</City>
<ZipPostalCode>94043</ZipPostalCode>
<Latitude>37.4192</Latitude>
<Longitude>-122.057</Longitude>
</Response>
هر فایل XML دارای یک شاخه اصلی هست که مثلا اینجا Response هست. با استفاده از
Dim rootnode As XmlNode = xmldoc.DocumentElement
وارد شاخه اصلی میشیم.
میبینید که که مقدار به اسم STATUS وجود داره که حالت پاسخ برگشتی رو نشون میده، اگر این مقدار OK باشه، یعنی ما جواب رو درست گرفتیم، اگر نه، مقدار اون برابر پیغام خطای تولید شده خواهد بود. مثلا من به جای یک مقدار آی پی، کلمه test رو وارد میکنم در این آدرس:
http://iplocationtools.com/ip_query.php?ip=test
میبینیم که مقدار Status برابر خواهد شد با Invalid IP
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Ip>test</Ip>
<Status>Invalid IP</Status>
<CountryCode></CountryCode>
<CountryName></CountryName>
<RegionCode></RegionCode>
<RegionName></RegionName>
<City></City>
<ZipPostalCode></ZipPostalCode>
<Latitude></Latitude>
<Longitude></Longitude>
</Response>
این اطلاعات رو من از دیدن فایل XML و تست کردن یک ورودی اشتباه به دست آوردم و همچنین خود سایت هم در این مورد توضیح داده. یعنی کار خارق العاده ای نیست پیدا کردن این اطلاعات :دی
بنابراین در کد اصلی اول مقدار Status رو میخونیم، اگر OK بود، مقدار زیرشاخه CountryName رو برمیگردونیم، البته در فایل XML شما میبینید اطلاعات دیگه ای هم به شما داده میشه که میتونین از همشون اصلا استفاده کنید در فانکشن های مختلف... اگر هم این Status مقدار غیر OK داشت، همون مقدار رو که متن خطای تولید شده هست برمیگردونیم.
کل سورس کلاس به این صورت هست:
Imports Microsoft.VisualBasic
Imports System.Xml
Public Class IPtoLocation
Public Shared Function GetCountry(ByVal IPAddress As String) As String
Dim apiURLaddress As String = "http://iplocationtools.com/ip_query.php?ip="
Dim webreq As New System.Net.WebClient
Dim outstream As New IO.StreamReader(webreq.OpenRead(apiURLaddress & IPAddress))
Dim xmldoc As New XmlDocument
xmldoc.Load(outstream)
If xmldoc.HasChildNodes Then
Dim rootnode As XmlNode = xmldoc.DocumentElement
If rootnode.SelectSingleNode("Status").ChildNodes(0).Value = "OK" Then
Return rootnode.SelectSingleNode("CountryName").ChildNodes(0).Value
Else
Return rootnode.SelectSingleNode("Status").ChildNodes(0).Value
End If
Else
Return "Error Loading XML file. Maybe Internet Connection is down!"
End If
End Function
End Class
حالا در یک وب فرم aspx ، یک تکست باکس و یک لیبل به همراه یک دکمه درست کنید. در event کلیک شدن دکمه بنویسید:
Label1.Text = IPtoLocation.GetCountry(TextBox1.Text)
داخل textbox هر مقداری دوست دارید بنویسید البته سعی کنید چند تا آی پی هم بهش بدید :دی و نتیجه رو ببینید.
به همین سادگی
*این مطالب از خودم میباشد! اگر در اون مورد اشتباهی میبینید، ممنون میشم که اعلام کنید و استفاده از این مطلب آزاد هست و اگر دوست دارید با انصاف باشید، منبع رو هم ذکر کنید.