python写后端api要学什么_一个六年经验的python后端是怎么学习用java写API的(4) RestAPI,dropwizard 的第一组API...

描述

廖雪峰java语法教程, 半天时间过一遍语法,看到集合那里即可

dropwizard文档 半天时间过一遍 Getting Started 部分

代码

parrot tag: first_api

dropwizard 与 django 的简单对比

dropwizard

java

└── com

└── reworkplan

├── ParrotApplication.java

├── bundles

│   ├── CorsBundle.java

│   └── MysqlBundle.java

├── common

│   ├── Constants.java

│   └── response

│   ├── MetaListResponse.java

│   └── MetaMapperResponse.java

├── config

│   └── ParrotConfiguration.java

├── mappers

│   ├── ArticleMapper.java

│   └── handlers

│   └── DateTimeTypeHandler.java

├── models

│   └── Article.java

├── modules

│   ├── ApplicationModule.java

│   └── InjectorFactory.java

└── resources

├── ArticlesResource.java

└── BasePath.java

django

├── common

│   ├── __init__.py

│   ├── constants.py

│   ├── data_structure.py

│   ├── db.py

│   ├── exceptions.py

│   ├── oauth_utils.py

│   ├── permissions.py

│   ├── rest.py

│   ├── sms.py

│   ├── tools.py

│   ├── upload.py

│   └── weixin.py

├── config

│   ├── __init__.py

│   ├── settings

│   │   ├── __init__.py

│   │   ├── common.py

│   │   ├── development.py

│   │   ├── private.example.py

│   │   └── production.py

│   ├── urls.py

│   └── wsgi.py

├── extracter

│   ├── __init__.py

│   ├── admin.py

│   ├── apps.py

│   ├── migrations

│   │   ├── 0001_initial.py

│   │   └── __init__.py

│   ├── models.py

│   ├── tests.py

│   ├── urls.py

│   └── views.py

├── manage.py

web 框架的设计都是大同小异的,概念映射如下:

主程序入口: django wsgi.py;dropwizard ParrotApplication.java

环境变量等常量配置:django settings目录;dropwizard Config 目录 ParrotConfiguration.java,另外还有个配置文件config/environment.yml

普通常量配置:django没有这个概念,我一般放在common.constants下;dropwizard我创建了个common Constants.java

路由定义:django 的 urls.py;dropwizard 他是放在Resource类上通过Path注解实现,然后在ParrotApplication.java中注册Path类

具体API实现:django 的 views.py 中继承自 APIView 的类,配置在urls.py中;dropwizard 的 Resource目录下的类,需要在然后在ParrotApplication.java中注册

数据库的ORM:django 中 的 models.py;dropwizard 使用 mybatis,对应 mappers目录下的类,每个mappers还要在还需resources的xml目录下添加mybatis格式的xml去写具体的sql,并且需要写一个jdbc的sqlsession,需要在ParrotApplication中注册mapper和sqlsession,要自己做很多的基础工作(返回db的datetime需要自己写时间格式的handler等等)

处理逻辑:django是直接在models上实现一些逻辑,这对应于dropwizard的service目录(代码写到这暂时没有逻辑需要处理所以没创建service),具体api接口需要柔和多个逻辑,django直接调用各个model上的逻辑+api内在写一部分;dropwizard则在resource.java里面调用各个service的Impl类组合逻辑

middleware:django 实现 middleware.py,在settings中配置,可以放在任何模块下;java放在一个叫做bundles的目录下,在ParrotApplication中注册

大概就是这样,另外java还有叫做注入的东西,所以我创建了modules目录 希望通过InjectorFactory做一些事情,暂时没调通

实现第一个 API Get /articles/{id}

实现 resource

通过Path注解定义api的路由

Produces注解说返回一个json

GET注解说明的restful的get方法

方法内的 PathParam注解是接受路由参数id

方法内则需要一个mapper去执行数据库的操作

定义一个自定义的reponse对象(或者不定义直接返回model对象),我习惯返回这两种格式: 列表 {"meta":{}, "data": []}, 单个元素或者普通数据 {"meta":{}, "data": {}}

@Path(BasePath.ARTICLE_API)

@Produces(APPLICATION_JSON)

public class ArticlesResource {

private final SqlSessionFactory sessionFactory;

public ArticlesResource(SqlSessionFactory sessionFactory) {

this.sessionFactory = sessionFactory;

}

@Path("/{id}")

@GET

@Timed

public MetaMapperResponse get(@NotNull @PathParam("id") Integer articleId) {

MetaMapperResponse response = new MetaMapperResponse();

try (SqlSession session = sessionFactory.openSession()) {

ArticleMapper articleMapper = session.getMapper(ArticleMapper.class);

Boolean isActive = true;

Article article = articleMapper.select(articleId, isActive);

response.setData(article);

}

return response;

}

}

实现mapper

实现一个interface,定义mapper的方法

然后需要在 resources的xml目录下实现这个mapper定义方法的sql,例如 java中定义了个Article select(@Param("id") Integer id, @Param("isActive") Boolean isActive), 那么xml里面就需要有这个东西的定义

xml中定义resultMap是指将sql返回的内容格式化到这个resultMap里面,类似django的serializer,但是并不智能,例如datetime他就不知道怎么处理,然后会报错,需要实现一个mappers.handlers.DateTimeTypeHandler, 然后在 bundles.MysqlBundle 里面注册这个handler,才能正确处理datetime格式的字段

xml中的parameterType="hashmap",对应于interface里面的Param注解,如果没有会报找不到参数

回调resource里面发现,ArticleMapper articleMapper = session.getMapper(ArticleMapper.class); mapper需要通过session.getMapper的形式,而session是在ParrotApplication中注册并且添加了ArticleMapper这个类, SqlSessionFactory sessionFactory = mysqlBundle.getSqlSessionFactory(); sessionFactory.getConfiguration().addMapper(ArticleMapper.class);。

public interface ArticleMapper {

Article select(@Param("id") Integer id, @Param("isActive") Boolean isActive);

List selectAll(@Param("isActive") Boolean isActive,

@Param("offset") Integer offset,

@Param("limit") Integer limit);

Integer countAll (@Param("isActive") Boolean isActive);

}

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT id, title, cover, description, is_active, created

FROM extracter_wxarticle WHERE id = #{id}

and is_active=#{isActive} and is_delete=0

SELECT count(*)

FROM extracter_wxarticle

WHERE

is_active=#{isActive} and is_delete=0

ParrotApplication

主入口在main,而run时候执行的命令是 server config/environment.yml,推测Enviroments读的是config/environment.yml

initialize和run的先后顺序目前我不清楚,可以看到initiallize里面注册的是middleware,run里面注册的是mapper和resource

public class ParrotApplication extends Application {

private final InjectorFactory injectorFactory;

private final MysqlBundle mysqlBundle;

public ParrotApplication() {

this.injectorFactory = new InjectorFactory();

this.mysqlBundle = new MysqlBundle();

}

public ParrotApplication(InjectorFactory injectorFactory) {

this.injectorFactory = injectorFactory;

this.mysqlBundle = new MysqlBundle();

}

@Override

public void initialize(Bootstrap bootstrap) {

bootstrap.addBundle(new TemplateConfigBundle());

bootstrap.addBundle(new Java8Bundle());

bootstrap.addBundle(new MultiPartBundle());

bootstrap.addBundle(new CorsBundle());

bootstrap.addBundle(mysqlBundle);

super.initialize(bootstrap);

}

@Override

public void run(ParrotConfiguration configuration, Environment environment) throws Exception {

SqlSessionFactory sessionFactory = mysqlBundle.getSqlSessionFactory();

sessionFactory.getConfiguration().addMapper(ArticleMapper.class);

environment.jersey().register(JodaTimeParamConverterProvider.class);

environment.jersey().register(new ArticlesResource(sessionFactory));

}

public static void main(String[] args) throws Exception {

new ParrotApplication(new InjectorFactory()).run(args);

}

}

接下来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值