个性化阅读
专注于IT技术分析

移动应用程序构建简单的REST API

本文概述

什么是REST?

代表性状态传输(REST)是基于HTTP的轻量级服务器, 可在类似于“常规”网站的网络服务器上运行。而不是以表示和数据的组合形式交付的HTML, 而是使用分隔符和分隔符(如JSON)以最小的格式显示数据。可以将其视为用于设计联网应用程序的体系结构样式, 或者将其视为交付Web服务的一种方式。 REST是可浏览的, 因此可以帮助开发人员修改和检查其代码的正确性, 因为只有数据显示在浏览器中。这是一种提供服务或访问数据的更安全的方法, 因为它不会暴露网站使用的数据库的不必要的表面积。一些著名的REST API来自Twitter和Facebook Graph。

REST是平台和语言独立的。你可以使用通常与网站创建相关的任何语言(例如PHP, Python或Ruby)编写REST API。 REST体系结构中使用了四种通常定义的方法。这些是创建, 读取, 更新和删除(CRUD)方法。也可以添加更专业的方法, 例如检索最受欢迎的前十项或所有用户的高分。这可以通过编写新方法或使用查询参数(例如/ api / items?top = 10)来实现。

HTTP方法和API端点

你可能还记得创建Web表单(同步)或Ajax请求(异步)调用时曾使用过GET和POST请求。 PUT和DELETE请求较少使用。然后, 如果你使用PHP, Python或其他语言编写了一个处理表单数据的应用程序, 那么你已经编写了自己的简单REST框架。 POST, GET, PUT和DELETE对应于创建, 读取, 更新和删除, 并且与基本数据库操作有关。 API端点描述了服务公开的数据上的可用操作。可以将它们视为提供数据的URL(GET请求)或可以向其提交数据的URL(POST请求)。可以使用许多数据格式, 但更常见的是JSON和XML。即使多次应用, GET / api / boats / 123456也会返回ID为123456的小船上的数据。

使用djangorestframework构建简单的REST API

我们将使用Django(Python MVC框架)和djangorestframework。 Djangorestframework是使用django(python)构建的, 专门用于通过REST框架公开数据。

首先, 你需要安装Python v2.7或更高版本以及Django 1.7.4或更高版本。如果不这样做, 请立即安装Python和Django。

你可以通过启动命令行并键入python命令来测试安装。一切顺利, 你应该看到版本信息。继续输入:

>>> import django
>>> print(django.get_version())
1.7.4

这验证你的系统上安装了Django。接下来, 我们构建Django项目:

$ django-admin.py startproject marine

这是创建的文件和文件夹的列表。

marine/
    manage.py
    marine/
        __init__.py
        settings.py
        urls.py
        wsgi.py

你可以通过执行以下命令检查一切是否按预期进行:

$ python manage.py runserver

这将启动Django开发网络服务器进行测试。成功后, 你将看到:

Performing system checks...

0 errors found
February 15, 2015 - 15:50:53
Django version 1.7.4, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

如果你打开URL http://127.0.0.1:8000/, 你将看到一个占位符网站。

现在, 我们有了该网站的裸露骨架。接下来, 我们将构建一个包含模型的应用程序(容器)(如在Model-View-Controller中一样)。模型是应用程序数据的来源。

输入:

$ python manage.py startapp fishes

将导致以下文件

fishes/
    __init__.py
    admin.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

在models.py文件中, 有django.db导入模型的导入行。向其添加以下代码。

class Fish(models.Model):
        name = models.CharField(max_length=255)
        created = models.DateTimeField('auto_now_add=True')
        active = models.BooleanField()

这将创建一个类, 该类公开鱼的名称, 创建日期以及数据行是否处于活动状态。你可以通过参考相关文档来更改字段类型。

现在, 将fishs应用添加到marine / settings.py文件中进行注册。通过在INSTALLED_APPS下执行此操作, 将鱼添加到列表中。运行python manage.py sql fish来查看我们激活应用程序时将运行的数据库模式SQL的预览。

BEGIN;
        CREATE TABLE "fishes_fish" (
            "id" integer NOT NULL PRIMARY KEY, "name" varchar(255) NOT NULL, "created" datetime NOT NULL, "active" bool NOT NULL
        )
    ;

    COMMIT;

要确认在默认sqlite数据库中创建了相关表, 请在旧版Django上键入python manage.py migration或python manage.py syncdb。 Django默认会创建身份验证表, 并在sqlite3数据库中创建空的fishes_fish表。提示符将询问你是否要创建超级用户, 因为这是你第一次运行Django。

如果由于某种原因没有提示你创建超级用户, 请在命令提示符下键入:

$ python manage.py createsuperuser

按照说明创建管理员帐户。 Django提供了一个内置的管理页面, 可让你插入和修改数据。需要通过编辑fishes文件夹中的admin.py文件来激活该功能。从django.contrib import admin之后添加以下代码

...
    from fishes.models import Fish
    admin.site.register(Fish)

我们将使用创建的帐户登录到管理页面。启动开发服务器:

$ python manage.py runserver

打开127.0.0.1:8000/admin, 然后输入超级用户ID和密码。你应该会看到带有“海军陆战队”列表的管理页面。单击Fishs添加或修改数据。添加一些数据。

是的你做到了!

至此, 我们已经建立了一个正常运行的Django网站。现在, 我们将通过下载并安装djangorestframework将其合并到站点中。要记住的一件事是将rest_framework添加到marine / settings.py中的INSTALLED_APPS列表中, 并将urls.py更改为

from django.contrib import admin
from rest_framework import routers
from fishes import views

router = routers.DefaultRouter()
#makes sure that the API endpoints work
router.register(r'api/fishes', views.FishViewSet)
admin.autodiscover()

urlpatterns = patterns('', # Examples:
    # url(r'^$', 'marine.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)

这段代码打开了对`djangorestframework至关重要的API路由, 并使用正则表达式来设置站点的有效URL。

当我们安装djangorestframework时, 它使我们能够使用序列化程序, 该序列化程序将从fish模型获得的数据展平为XML或JSON字符串格式。要为fishes模型创建序列化器, 我们在fishes文件夹下创建一个文件, 并将其命名为serializers.py。这是该文件的内容:

from fishes.models import Fish
from rest_framework import serializers

class FishSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Fish
        fields = ('name', 'active', 'created')

在views.py文件中, 添加:

from rest_framework import viewsets
from rest_framework import permissions
from fishes.models import Fish
from fishes.serializers import FishSerializer

# Create your views here.
class FishViewSet(viewsets.ModelViewSet):
    # this fetches all the rows of data in the Fish table
    queryset = Fish.objects.all()
    serializer_class = FishSerializer

现在, 如果你打开http://127.0.0.1:8000/api/fishes/, 你将看到可浏览的API。

HTTP 200 OK
Content-Type: application/json
Vary: Accept
Allow: GET, POST, HEAD, OPTIONS

[
    {
        "name": "Dory", "created": "2014-06-21T04:23:01.639Z", }, {
        "name": "Angel", "created": "2014-07-21T04:23:01.639Z", }, {
        "name": "Clown", "created": "2014-08-21T04:23:01.639Z", }
]

你可以在GitHub上找到REST API应用程序的源代码。没有数据, 因此下载后, 你将需要在旧版Django上运行python manage.py migration或python manage.py syncdb。

iOS移动应用

接下来, 我们将完成创建从API接收数据的移动应用所需的关键步骤。我们正在使用UITableView在列表中显示数据。在XCode 6.3.1(撰写本文时为最新版本)中, 创建一个新项目

文件>新建>项目> iOS应用程序>单视图应用程序

  • 产品名称:鱼
  • 语言:Objective-C
  • 设备:iPhone(默认为通用, 包括iPhone和iPad)
  • 暂时不使用核心数据。

选择一个位置来保存你的项目, 然后单击“创建”。我们将处理Fishes文件夹中包含的文件。

默认情况下, 该项目具有一个View Controller。我们希望将REST API中的数据显示为列表, 因此将改用Table View Controller。创建一组新的Objective-C文件(“文件”>“新建”>“文件”>“ iOS源”>“ Cocoa Touch类”)。

  • 类:TableViewController
  • 子类:UITableViewController
  • 我们不需要XIB文件

将这些新文件保存在Fishes文件夹中。

打开Main.storyboard, 转到“对象库”, 然后将“ Table View Controller”对象拖到情节提要中。选择并删除默认的View Controller。确保在检查器中, 选中“选定的表视图控制器的是初始视图控制器”复选框。

显示文档大纲或导航器以查看Interface Builder上可用的组件

–在Main.storyboard中, 展开“表视图控制器”以显示“表视图单元格”, 选择“属性”检查器, 然后输入FishCell作为标识符。这会将Interface Builder故事板上的单元格链接到代码。 –将样式从基本更改为字幕。这使我们可以显示由cell.detailTextLabel设置的值。 –在“表视图控制器”场景下选择“表视图控制器”, 单击“身份检查器”, 然后在“自定义类”>“类”中输入TableViewController。这会将整个场景链接到TableViewController.m文件。

更改自定义类

接下来, 我们添加使该应用程序执行某些操作的代码。该代码演示了如何使用简单的NSArray显示在TableViewController.m中进行硬编码的数据。用以下内容替换所有现有功能。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
    // Return the number of rows in the section.  I currently have three rows we would like to show
    return 3;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FishCell" forIndexPath:indexPath];
    //temporary data to demonstrate the structure of a NSDictionary in an NSArray, which is the general structure of a JSON, this can be removed in a later stage
    NSArray *fishes = @[
                        @{@"name": @"Dory", @"created": @"2014-06-21T04:23:01.639Z"}, @{@"name": @"Angel", @"created": @"2014-07-21T04:23:01.639Z"}, @{@"name": @"Clown", @"created": @"2014-08-21T04:23:01.639Z"}
                        ];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"FishCell"];
    }
    //We will replace fishes with fishJson once we have code that downloads from the REST api
    [cell.textLabel setText:[[fishes objectAtIndex:indexPath.row] objectForKey:@"name"] ];
    [cell.detailTextLabel setText:[[fishes objectAtIndex:indexPath.row] objectForKey:@"created"]];
    return cell;
}

现在, 我们可以测试这个简单的应用程序。选择产品>运行。

接下来, 我们需要从使用djangorestframework发布的REST API中获取JSON。我们通过在接口级别进行注册并将其与@ propertyand @ synthesize进行合成, 从而建立了一个名为fishJson的NSArray对象。这将替换setter和getter的代码。然后, 我们替换在numberOfRowsInSection中拥有的代码, 在这里我们将fishs替换为fishJson, 后者包含来自REST API的JSON。再次替换任何现有的函数或声明。

@interface TableViewController ()
@property (strong) NSArray *fishJson;
@end

@implementation TableViewController
@synthesize fishJson;
- (void) downloadData {
    //I use NSMutableString so we could append or replace parts of the URI with query parameters in the future
    NSMutableString *remoteUrl = [NSMutableString stringWithFormat:@"http://127.0.0.1:8000/api/fishes/?format=%@", @"json"];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:remoteUrl] ];
    NSError *jsonError = nil;
    NSHTTPURLResponse *jsonResponse = nil;

    NSData *response;
    do {
        response = [NSURLConnection sendSynchronousRequest:request returningResponse:&jsonResponse error:&jsonError];
    } while ([jsonError domain] == NSURLErrorDomain);

    if([jsonResponse statusCode] != 200) {
        NSLog(@"%ld", (long)[jsonResponse statusCode]);
    } else {
        NSLog(@"%@", @"200 OK");
    }
    NSError* error;
    if(response) {
        //fishJson was defined earlier near the top as a NSArray object
        fishJson = [NSJSONSerialization
                JSONObjectWithData:response
                options:kNilOptions
                error:&error];
    }
}

我们需要确保该方法在应用启动时运行, 并在viewDidLoad下面添加以下内容:

[self downloadData];

在这里, 我们更新numberOfRowsInSection方法。此代码确保行数与fishJson数组中包含的元素数匹配。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return [fishJson count];
}

更新cellForRowAtIndexPath方法, 以便它从REST提要中加载条目:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FishCell" forIndexPath:indexPath];

    // Configure the cell...
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"FishCell"];
    }
    [cell.textLabel setText:[[fishJson objectAtIndex:indexPath.row] objectForKey:@"name"] ];
    [cell.detailTextLabel setText:[[fishJson objectAtIndex:indexPath.row] objectForKey:@"created"]];
    return cell;
}

现在, 我们有了一个可以运行的简单移动应用程序, 以显示从在线或本地REST API获取的数据。你可以在上面的同一存储库中找到iOS应用程序的代码。本教程包含许多“现实世界”应用程序中常见的概念和组件。如果你遇到任何问题或有任何疑问或意见, 请在下面的评论中告诉我。

赞(0)
未经允许不得转载:srcmini » 移动应用程序构建简单的REST API

评论 抢沙发

评论前必须登录!